考虑以下 PHP 代码:
<?php
$key = "1234567812345678";
$iv = "1234567812345678";
$data = "Test string";
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
$key,
$data,
MCRYPT_MODE_CBC,
$iv);
print "Encoded1: " . base64_encode($encrypted) . "\n";
$key = "12345678123456781234567812345678";
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
$key,
$data,
MCRYPT_MODE_CBC,
$iv);
print "Encoded2: " . base64_encode($encrypted) . "\n";
运行时,这会产生输出:
Encoded1: iz1qFlQJfs6Ycp+gcc2z4w==
Encoded2: n3D26h/m8CSH0CE+z6okkw==
请注意,我从PHP Java AES CBC Encryption Different Results中窃取了第一段代码
现在 - 这是问题:
在第一种情况下,传入的密钥是一个 16 个字符的字符串。如果每个单独的字符都被解释为一个 8 位的数量,这将给出预期的 128 位密钥大小。事实上,我在上面引用的 StackOverflow 页面上的 Java 代码正是这样做的,并获得了与 PHP 相同的结果。
在上面的第二次调用中mcrypt_encrypt
,我将密钥的长度加倍。 mcrypt_encrypt
很高兴地接受了这一点,但产生了与第一种情况不同的加密输出。因此,很明显,它认为这是一个不同的密钥——例如,它不会只取前 128 位并丢弃任何过去的位。
那么,如何mcrypt_encrypt
处理输入的密钥字符串以得出MCRYPT_RIJNDAEL_128
算法所需的 128 位密钥呢?
如果它有任何区别,我特别感兴趣的情况是像我的第二个示例一样传入 32 个字符的字符串 - 我必须创建一个匹配的解密例程(在 Java 中),所以我需要弄清楚如何在这种情况下实际上生成了密钥。我引用的页面有非常好的 Java 代码(它适用于我所有的测试用例)——我只是缺少正确的关键字节集。