使用16字节密钥在PHP中进行3DES CBC加密

时间:2015-12-01 22:25:26

标签: php encryption 3des cbc-mode

我一直在尝试用PHP制作3DES算法。我用Java制作它并且运行良好,但PHP版本给了我不同的结果;这是我的代码:

function String2Hex($string){
    $hex='';
    for ($i=0; $i < strlen($string); $i++){
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}

function hexToAscii($inputHex) {
    $inputHex = str_replace(' ', '', $inputHex);
    $inputHex = str_replace('\x', '', $inputHex);
    $ascii = pack('H*', $inputHex);
    return $ascii;
}

$cipher = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');

$iv =  '0000000000000000';

$key = '75ABFD405D018A9BD0E66D23DA3B6DC8';
printf("KEY: %s\n", String2Hex($key));

$cleartext = '0436A6BFFFFFFFA8';
printf("<br>TEXT: %s\n\n", $cleartext);

if (mcrypt_generic_init($cipher, hexToAscii($key), $iv) != -1)
{
    $cipherText = mcrypt_generic($cipher, hexToAscii($cleartext));
    mcrypt_generic_deinit($cipher);

    printf("<br><br>3DES encrypted:\n%s\n\n", strtoupper(bin2hex($cipherText)));
}

必须给我:76FB62FB3AFD6677
但它给了我:E01BD1085F0126A2

我该怎么办?

1 个答案:

答案 0 :(得分:1)

三重DES定义为192位密钥大小(168位不带奇偶校验)。这假设有三个独立的子键。由于您只有一个128位,因此需要将两个键拉伸为三个子键。由于3DES通常作为加密 - 解密 - 加密(EDE)方案执行,因此第一个和最后一个子密钥可以相同。

如果您当前的密钥为K1 || K2,那么您可以尝试使用K1 || K2 || K1K2 || K1 || K2作为最终密钥。我已经为你尝试了,第一个建议有效。

另外,您忘了从Hex解码IV。这是完整的代码:

function String2Hex($string){
$hex='';
for ($i=0; $i < strlen($string); $i++){
    $hex .= dechex(ord($string[$i]));
}
return $hex;
}

function hexToAscii($inputHex) {
    $inputHex = str_replace(' ', '', $inputHex);
    $inputHex = str_replace('\x', '', $inputHex);
    $ascii = pack('H*', $inputHex);
    return $ascii;
}

$cipher = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');

$iv =  '0000000000000000';

//$key = '75ABFD405D018A9BD0E66D23DA3B6DC8';
$key = '75ABFD405D018A9BD0E66D23DA3B6DC875ABFD405D018A9B';
printf("KEY: %s\n", $key);

$cleartext = '0436A6BFFFFFFFA8';
printf("<br>TEXT: %s\n\n", $cleartext);

if (mcrypt_generic_init($cipher, hexToAscii($key), hexToAscii($iv)) != -1)
{
    $cipherText = mcrypt_generic($cipher, hexToAscii($cleartext));
    mcrypt_generic_deinit($cipher);

    printf("<br>3DES encrypted:\n%s\n\n", strtoupper(bin2hex($cipherText)));
}

输出:

KEY: 75ABFD405D018A9BD0E66D23DA3B6DC875ABFD405D018A9B
TEXT: 0436A6BFFFFFFFA8
3DES encrypted: 76FB62FB3AFD6677