找出由PHP的mcrypt创建的确切密钥 [英] Figuring out the exact key created by PHP's mcrypt

查看:76
本文介绍了找出由PHP的mcrypt创建的确切密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在维护的PHP应用程序使用Rijndael_256和带有mcrypt的EBC_MODE加密.有趣的是,密钥不是256位长,而只有160位.根据

A PHP application I'm maintaining uses Rijndael_256 with EBC_MODE encryption with mcrypt. Fun has it that the key isn't 256 bits long, but only 160. According to the mcrypt_encrypt documentation the key is padded with \0 to get the required size if it's too small.

用于加密数据的密钥.如果小于 所需的密钥大小,用'\ 0'填充.最好不要使用 密钥的ASCII字符串.

The key with which the data will be encrypted. If it's smaller than the required keysize, it is padded with '\0'. It is better not to use ASCII strings for keys.

这似乎发生在 mcrypt.c中的第1186行,并在第1213行中修改密钥.

This seem to happen at around the start of line 1186 in mcrypt.c and modifying the key at line 1213.

所以可以说我们的$key = 'abcdefghijkm';太短了,但是PHP的mcrypt实现可确保在使用RIJNDAEL_256时将其扩展为32个字符(或256位).最终的密钥是什么样的?

So lets say we've got $key = 'abcdefghijkm'; which is too short, but PHP's implementation of mcrypt makes sure it's extended to 32 characters (or 256 bit) when using RIJNDAEL_256. What will the final key look like?

我之所以这样问,是因为正在构建另一个使用相同加密数据但使用另一种语言的应用程序.确切地说是Perl,我正在使用 Crypto::Rijndael .对于给定的示例密钥,要重新解密数据,我必须提供给Crypto::Rijndael(或与此有关的任何其他密钥)的确切密钥是什么?

I'm asking this because another application is being built that uses the same encrypted data, but is in another language. Perl to be exact and I'm using Crypto::Rijndael. For the given example key, what is the exact key I would have to feed to Crypto::Rijndael (or any other for that matter) to be able to decrypt the data again?

更新

使用Perl,我可以生成一个\ c填充了pack('a32', 'my secret key');(或Z32)的密钥,length()将报告32,并且Crypt::Rijndael模块接受该密钥.查看PHP的mcrypt的来源,这应该是正在生成的密钥(填充\ 0),但根本不会接受它.

With Perl I can generate a key that's \0 padded doing pack('a32', 'my secret key'); (or Z32), length() will report 32 and the Crypt::Rijndael module accepts the key. Looking at the source of PHP's mcrypt this should be the key that's being generated (\0 padded), but it simply won't take it.

从理论上讲,PHP pack('a32', 'my secret key');应该导致PHP的mcrypt生成相同的\ 0填充密钥,但这不是事实.

In theory in PHP pack('a32', 'my secret key'); should result in the same \0 padded key that PHP's mcrypt generates, but this isn't the case.

我几乎要再次加密所有内容,但要使用新密钥.这花费了太多时间.

I'm very close to just encrypt everything again but with a new key. This is taking too much time.

推荐答案

问题不是键的填充,而是您使用的是两种不同的块大小.在PHP中,使用MCRYPT_RIJNDAEL_256使用的块大小为256位.但是,在使用Crypt::Rijndael的perl中,他们指出:

The issue isn't the key's padding, it's that you're using two different block sizes. In PHP, using MCRYPT_RIJNDAEL_256 uses a block size of... 256 bits. However, in perl using Crypt::Rijndael, they note:

块大小
Rijndael的块大小为16个字节(128位),尽管该算法实际上支持任何字节大小的块大小. 128位是AES指定的块大小,所以这就是我们所支持的.

blocksize
The blocksize for Rijndael is 16 bytes (128 bits), although the algorithm actually supports any blocksize that is any multiple of our bytes. 128 bits, is however, the AES-specified block size, so this is all we support.

因此,没有密钥可以在这些不同算法之间进行转换.您可以在PHP中切换到128位:

So there's no key that will allow for conversion between those different algorithms. You can either switch to 128 bits in PHP:

<?
$key = "abcdefghijklmnopqrstuvwxyz";
$data = "Meet me at 11 o'clock behind the monument.";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB, nil);
echo bin2hex($crypttext) . "\n";
// prints c613d1804f52f535cb4740242270b1bcbf85151ce4c874848fd1fc2add06e0cc2d26b6403feef4a8df18f7dd7f8ac67d
?>

使用Crypt :: Rijndael:哪个Perl可以毫无问题地解密:

Which Perl can decrypt without a problem using Crypt::Rijndael:

use Crypt::Rijndael;
$key = "abcdefghijklmnopqrstuvwxyz\0\0\0\0\0\0";
$crypttext = "c613d1804f52f535cb4740242270b1bcbf85151ce4c874848fd1fc2add06e0cc2d26b6403feef4a8df18f7dd7f8ac67d";
$cipher = Crypt::Rijndael->new($key, Crypt::Rijndael::MODE_ECB());
print $cipher->decrypt(pack('H*', $crypttext));
# prints "Meet me at 11 o'clock behind the monument."

或者您可以切换到支持更多块大小的其他Perl模块,例如 Crypt :: Rijndael_PP :

Or you can switch to a different Perl module that supports more block sizes, e.g., Crypt::Rijndael_PP:

# Same PHP code except using MCRYPT_RIJNDAEL_256
# prints f38469ec9deaadbbf49bb25fd7fc8b76462ebfbcf149a667306c8d1c033232322ee5b83fa87d49e4e927437647dbf7193e6d734242d583157b492347a2b1514c

Perl:

use Crypt::Rijndael_PP ':all';
$key = "abcdefghijklmnopqrstuvwxyz\0\0\0\0\0\0";
$crypttext = "f38469ec9deaadbbf49bb25fd7fc8b76462ebfbcf149a667306c8d1c033232322ee5b83fa87d49e4e927437647dbf7193e6d734242d583157b492347a2b1514c";
print rijndael_decrypt(unpack('H*', $key), MODE_ECB, pack('H*', $crypttext), 256, 256);
# prints "Meet me at 11 o'clock behind the monument."

这篇关于找出由PHP的mcrypt创建的确切密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆