如何使用OpenSSL解密使用了使用ASCII密钥的Mcrypt生成的值?

时间:2017-08-10 06:29:09

标签: php openssl mcrypt

我需要能够使用在PHP下使用Mcrypt生成的OpenSSL来解密值。

我有这个工作,除了用于加密它们的密钥是ascii。

以下是我的代码,演示了一个工作案例,当密钥是MD5时,OpenSSL可以解密用Mcrypt加密的值。

<?php
$message = 'test';
$key = md5('Quigibo');

$iv = openssl_random_pseudo_bytes(0);

$encrypted = mcrypt_encrypt(
    MCRYPT_BLOWFISH,
    $key,
    $message,
    MCRYPT_MODE_ECB,
    $iv
);

$decrypted = openssl_decrypt(
    $encrypted,
    'bf-ecb',
    $key,
    OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,
    $iv
);

$trimDecrypted = rtrim($decrypted);

var_export(
    [
        'Original message' => $message,
        'Encrypted' => bin2hex($encrypted),
        'Decrypted' => $decrypted,
        'Trim decrypted' => $trimDecrypted,
        'Message length' => mb_strlen($message, '8bit'),
        'Decrypted length' => mb_strlen($decrypted, '8bit'),
        'Message == decrypted' => $message === $trimDecrypted
    ]
);

但是,如果您将$key更改为值&#34; Quigibo&#34; (与该值的MD5哈希相反)无法使用OpenSSL解码加密值。

在使用OpenSSL之前,是否有一种编码形式可以应用于ASCII密钥,以便正确解密该值?

1 个答案:

答案 0 :(得分:1)

修改回答:

OpenSSL中存在一个错误,它将Blowfish的密钥填充为16字节,这是不正确的,因为密码支持可变长度密钥。他们最近添加了一个标志来解决这个问题 - OPENSSL_DONT_ZERO_PAD_KEY - 但它仅在一周前发布的php 7.1.8中可用...相关错误:https://bugs.php.net/bug.php?id=72362

解决方法是手动循环密钥并将其提供给OpenSSL:

$keylen = (floor(mb_strlen($key, '8bit')/8)+1)*56;
$key_cycled = substr(str_repeat($key,ceil($keylen/strlen($key))),0,$keylen);

$decrypted = openssl_decrypt(
$encrypted,
'bf-ecb',
$key_cycled,
OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,
$iv
);