计算PHP创建的确切密钥';s mcrypt
我维护的一个PHP应用程序使用Rijndael_256和带有mcrypt的EBC_模式加密。有趣的是,密钥不是256位长,而是只有160位。根据文档,如果密钥太小,则会用\0填充该密钥以获得所需的大小 用于加密数据的密钥。如果它小于 所需的密钥大小,用“\0”填充。最好不要使用 键的ASCII字符串 这似乎发生在第1213行的开始和修改关键点附近 假设我们有计算PHP创建的确切密钥';s mcrypt,php,mcrypt,rijndael,Php,Mcrypt,Rijndael,我维护的一个PHP应用程序使用Rijndael_256和带有mcrypt的EBC_模式加密。有趣的是,密钥不是256位长,而是只有160位。根据文档,如果密钥太小,则会用\0填充该密钥以获得所需的大小 用于加密数据的密钥。如果它小于 所需的密钥大小,用“\0”填充。最好不要使用 键的ASCII字符串 这似乎发生在第1213行的开始和修改关键点附近 假设我们有$key='abcdefghijkm'太短,但PHP的mcrypt实现确保在使用RIJNDAEL_256时将其扩展到32个字符(或256位)
$key='abcdefghijkm'代码>太短,但PHP的mcrypt实现确保在使用RIJNDAEL_256时将其扩展到32个字符(或256位)。最后一把钥匙是什么样子的
我这样问是因为正在构建另一个应用程序,它使用相同的加密数据,但使用另一种语言。确切地说,我使用的是Perl。对于给定的示例密钥,为了能够再次解密数据,我必须向Crypto::Rijndael
(或任何其他相关内容)提供的确切密钥是什么
更新
使用Perl,我可以生成一个\0填充在pack('a32','my secret key')中的密钥
(或Z32
),length()
将报告32,并且Crypt::Rijndael
模块接受密钥。查看PHP的mcrypt的源代码,这应该是正在生成的键(\0填充),但它根本不会接受它
理论上,在PHPpack('a32','my secret key')
应该产生与PHP的mcrypt生成的\0填充键相同的\0填充键,但事实并非如此
我非常接近于再次加密所有内容,但使用新密钥。这花费了太多时间。'\0'表示NULL,它的十六进制值是00!
所以我测试了3个代码,它们返回的都是相同的:)
让mcrypt_encrypt执行“\0”填充
添加了PHP空值
添加了PHP转换的0十六进制值
代码:
function encryptThis($text,$key){
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
return ($crypttext);
}
echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz"))."<br/>";
echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz" . NULL . NULL . NULL . NULL . NULL . NULL))."<br/>";
echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz" . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0)))."<br/>";
?>
函数加密此($text,$key){
$iv_size=mcrypt_get_iv_size(mcrypt_RIJNDAEL_256,mcrypt_MODE_ECB);
$iv=mcrypt\u create\u iv($iv\u大小,mcrypt\u兰德);
$crypttext=mcrypt_encrypt(mcrypt_RIJNDAEL_256,$key,$text,mcrypt_MODE_ECB,$iv);
返回($文本);
}
echo bin2hex(加密此(“11点在纪念碑后面见我。”,“abcdefghijklmnopqrstuvwxyz”)。“
”;
echo bin2hex(加密此(“11点在纪念碑后面见我。”,“abcdefghijklmnopqrstuvwxyz.NULL.NULL.NULL.NULL.NULL”)。“
”;
echo bin2hex(加密此(“11点在纪念碑后面见我。”,“abcdefghijklmnopqrstuvwxyz”)。hex2bin(0)。hex2bin(0)。hex2bin(0)。hex2bin(0)。hex2bin(0)。hex2bin(0))。“
”;
?>
问题不在于键的填充,而是使用了两种不同的块大小。在PHP中,使用MCRYPT_RIJNDAEL_256
使用块大小。。。256位。但是,在使用Crypt::Rijndael的perl中,他们注意到:
块大小
Rijndael的块大小是16个字节(128位),尽管该算法实际上支持任何字节数的任意倍数的块大小128位是AES指定的块大小,因此这是我们所支持的全部
因此,没有允许在这些不同算法之间进行转换的密钥。您可以在PHP中切换到128位:
<?
$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
?>
或者,您可以切换到支持更多块大小的不同Perl模块,例如:
Perl:
你试过用0填充它吗?是的,但是运气不好。记住,结果可能不是可打印的字符,所以不要依赖控制台/页面输出来确定键的实际外观。但是,如果您将生成的密钥写入二进制文件,您应该能够将其拉入您的perl脚本并成功使用它。我正在使用已使用PHP的mcrypt_encrypt
加密的纯文本进行尝试,并尝试使用perl的Crypt::Rijndael
进行解密。我需要知道的是,当PHP的mcrypt_encrypt
使用它时,实际的密钥是什么样子的:-)。请原谅我没有直接回答这个问题,但我认为这是个坏主意。如果您的密钥是密码,请首先使用KDF(例如PBKDF2、bcrypt、scrypt)扩展您的值,然后使用结果加密数据。我很高兴让mcrypt\u encrypt
进行\0填充。我需要确切的密钥,以便在另一种编程语言中使用它。谢谢你提到0x00,我忘了那个。不知道perl的undef
是否相同(怀疑是否相同)。它必须是32个字符。在本例中,字母表是26,32-26=6,因此必须添加6个空值或0x00:)现在格式混乱。实际上,$key1
和$key2
的长度完全相同,因此mcrypt_encrypt
仍在处理填充。这同样适用于$key3
。因此,它们给出相同的结果也就不足为奇了,因为对于PHP,它们都包含“abcdefghijklmnopqrstuvwxyz”
。因此最后一个键是“abcdefghijklmnopqrstuvwxyz”。无效的无效的无效的无效的无效的无效
…因为strlen()
以字节为单位计算字符串的长度,所以我希望它也计算\0,因为这也是一个字节。因为我们还不能确定在mcrypt修改键字符串之前PHP对字符串做了什么,所以仍然不能确定字符串最终应该是什么样子。谢谢,我已经开始认为blocksize与此有关,但还没有时间检查它。我想我将使用Crypt::Rijndael_PP
那么。嗯,虽然$key
实际上是256位长Crypt::Rijndael_PP
仍然在它后面附加0。在我看来里面好像有个bug?@HtbaaCrypt::Rijndael_PP
不像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."
# Same PHP code except using MCRYPT_RIJNDAEL_256
# prints f38469ec9deaadbbf49bb25fd7fc8b76462ebfbcf149a667306c8d1c033232322ee5b83fa87d49e4e927437647dbf7193e6d734242d583157b492347a2b1514c
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."