将我的加密库从Mcrypt升级到OpenSSL [英] Upgrading my encryption library from Mcrypt to OpenSSL

查看:138
本文介绍了将我的加密库从Mcrypt升级到OpenSSL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用下面通常引用的加密库。我想从Mcrypt将其升级到OpenSSL,以便我不再使用不推荐的库。



我正在尝试找出是否有可能。我已经做了一些研究,但我发现有冲突的信息:



这篇文章说,使用Mcrypt加密的OpenSSL解密数据是不可能的。
https://stackoverflow.com/a/19748494/5834657



但是,这篇文章说可以使用填充。看来我的函数使用填充。这是正确的填充类型需要做这项工作吗?
https://stackoverflow.com/a/31614770/5834657

 <?php 

命名空间Utilities\Encryption;

/ **
*处理任意数据的安全加密和解密的类
*
*请注意,这不仅仅是直接加密。它还有一些其他
*功能,使加密数据更加安全。请注意,用于解密数据的任何
*其他实现将必须执行相同的确定的
*操作。
*
*安全优点:$ b​​ $ b *
* - 使用按键拉伸
* - 隐藏初始化向量
* - HMAC验证源数据
*
* /

class加密{

/ **
* @var string $ cipher用于此实例的mcrypt密码
* /
protected $ cipher ='';

/ **
* @var int $ mode使用mcrypt密码模式
* /
protected $ mode ='';

/ **
* @var int $ rounds进入PBKDF2进行密钥生成的轮数
* /
protected $ rounds = 100;

/ **
*构造函数!
*
* @param string $ cipher用于此实例的MCRYPT_ * cypher
* @param int $ mode用于此实例的MCRYPT_MODE_ *模式
* @param int $ rounds关键字上的PBKDF2轮次数
* /
public function __construct($ cipher,$ mode,$ rounds = 100){
$ this-> cipher = $密码;
$ this-> mode = $ mode;
$ this-> rounds =(int)$ rounds;
}

/ **
*使用提供的密钥解密数据
*
* @param string $ data加密的数据解密
* @param string $ key用于解密的密钥
*
* @returns string | false如果解密成功,返回的字符串
*如果不是
则为false * /
public function decrypt($ data,$ key){
$ salt = substr($ data,0,128);
$ enc = substr($ data,128,-64);
$ mac = substr($ data,-64);

list($ cipherKey,$ macKey,$ iv)= $ this-> getKeys($ salt,$ key);

if($ mac!== hash_hmac('sha512',$ enc,$ macKey,true)){
return false;
}

$ dec = mcrypt_decrypt($ this-> cipher,$ cipherKey,$ enc,$ this->模式,$ iv);

$ data = $ this-> unpad($ dec);

return $ data;
}

/ **
*使用提供的密钥加密提供的数据
*
* @param string $ data要加密的数据
* @param string $ key使用
*
* @returns字符串进行加密的密钥加密数据
* /
public function encrypt($ data,$ key){
$ salt = mcrypt_create_iv(128,MCRYPT_DEV_URANDOM);
list($ cipherKey,$ macKey,$ iv)= $ this-> getKeys($ salt,$ key);

$ data = $ this-> pad($ data);

$ enc = mcrypt_encrypt($ this-> cipher,$ cipherKey,$ data,$ this->模式,$ iv);

$ mac = hash_hmac('sha512',$ enc,$ macKey,true);
返回$ salt。 $ enc。 $ MAC;
}

/ **
*生成一组给定随机盐和主键的键
*
* @param string $ salt A随机字符串更改密钥每个加密
* @param string $ key提供的密钥加密
*
* @returns数组一个密钥数组(密钥,一个mac密钥,和$ IV
* /
protected function getKeys($ salt,$ key){
$ ivSize = mcrypt_get_iv_size($ this-> cipher,$ this-> mode);
$ keySize = mcrypt_get_key_size($ this-> cipher,$ this->模式);
$ length = 2 * $ keySize + $ ivSize;

$ key = $ this-> pbkdf2('sha512',$ key,$ salt,$ this-> rounds,$ length);

$ cipherKey = substr($ key,0,$ keySize);
$ macKey = substr($ key,$ keySize,$ keySize);
$ iv = substr($ key,2 * $ keySize);
返回数组($ cipherKey,$ macKey,$ iv);
}

/ **
*使用PBKDF2算法弹出密钥
*
* @see http://en.wikipedia.org/ wiki / PBKDF2
*
* @param string $ algo使用
* @param string的算法$ key拉伸的关键
* @param string $ salt随机盐
* @param int $ rounds导出的轮数
* @param int $ length输出键的长度
*
* @returns string派生键。
* /
protected function pbkdf2($ algo,$ key,$ salt,$ rounds,$ length){
$ size = strlen(hash($ algo,'',true)) ;
$ len = ceil($ length / $ size);
$ result =''; ($ i = 1; $ i $ = $ len; $ i ++){
$ tmp = hash_hmac($ algo,$ salt。pack('N',$ i),$ key ,真)
$ res = $ tmp;
($ j = 1; $ j <$ rounds; $ j ++){
$ tmp = hash_hmac($ algo,$ tmp,$ key,true);
$ res ^ = $ tmp;
}
$ result。= $ res;
}
返回substr($ result,0,$ length);
}

protected function pad($ data){
$ length = mcrypt_get_block_size($ this-> cipher,$ this-> mode);
$ padAmount = $ length - strlen($ data)%$ length;
if($ padAmount == 0){
$ padAmount = $ length;
}
返回$数据。 str_repeat(chr($ padAmount),$ padAmount);
}

protected function unpad($ data){
$ length = mcrypt_get_block_size($ this-> cipher,$ this-> mode);
$ last = ord($ data [strlen($ data) - 1]);
if($ last> $ length)return false;
if(substr($ data,-1 * $ last)!== str_repeat(chr($ last),$ last)){
return false;
}
return substr($ data,0,-1 * $ last);
}
}






更新:我一直在尝试使用OpenSSL通过将库转换为OpenSSL解密使用Mcrypt加密的字符串。



然后,我使用密钥加密字符串并使用以下代码和相同的密钥尝试解密该值。不过我只是得到一个空白的回应。如果我注释掉:



$ data = $ this-> unpad($ dec)



函数我得到一个字符串,但它只是混乱的字符(很喜欢它看起来当它是第一次加密。)

 <? php 

命名空间Utilities\Encryption;

/ **
*处理任意数据的安全加密和解密的类
*
*请注意,这不仅仅是直接加密。它还有一些其他
*功能,使加密数据更加安全。请注意,用于解密数据的任何
*其他实现将必须执行相同的确定的
*操作。
*
*安全优点:$ b​​ $ b *
* - 使用按键拉伸
* - 隐藏初始化向量
* - HMAC验证源数据
*
* /
class EncryptionOpenSsl {

/ **
* @var string $ cipher用于此实例的mcrypt密码
* /
protected $ cipher ='';

/ **
* @var int $ mode使用mcrypt密码模式
* /
protected $ mode ='';

/ **
* @var int $ rounds进入PBKDF2进行密钥生成的轮数
* /
protected $ rounds = 100;

/ **
*构造函数!
*
* @param string $ cipher用于此实例的MCRYPT_ * cypher
* @param int $ mode用于此实例的MCRYPT_MODE_ *模式
* @param int $ rounds关键字上的PBKDF2轮次数
* /
public function __construct($ cipher,$ rounds = 100){
$ this-> cipher = $ cipher;
// $ this-> mode = MCRYPT_MODE_CBC;
$ this-> rounds =(int)$ rounds;
}

/ **
*使用提供的密钥解密数据
*
* @param string $ data加密的数据解密
* @param string $ key用于解密的密钥
*
* @returns string | false如果解密成功,返回的字符串
*如果不是
则为false * /
public function decrypt($ data,$ key){
$ salt = substr($ data,0,128);
$ enc = substr($ data,128,-64);
$ mac = substr($ data,-64);

list($ cipherKey,$ macKey,$ iv)= $ this-> getKeys($ salt,$ key);

if($ mac!== hash_hmac('sha512',$ enc,$ macKey,true)){
return false;
}
$ dec = openssl_decrypt($ enc,$ this-> cipher,$ key,OPENSSL_RAW_DATA,$ iv);
// $ dec = mcrypt_decrypt($ this-> cipher,$ cipherKey,$ enc,$ this->模式,$ iv);

$ data = $ this-> unpad($ dec);

return $ data;
}

/ **
*使用提供的密钥加密提供的数据
*
* @param string $ data要加密的数据
* @param string $ key使用
*
* @returns字符串进行加密的密钥加密数据
* /
public function encrypt($ data,$ key){
$ salt = mcrypt_create_iv(128,MCRYPT_DEV_URANDOM);
list($ cipherKey,$ macKey,$ iv)= $ this-> getKeys($ salt,$ key);

$ data = $ this-> pad($ data);

$ enc = mcrypt_encrypt($ this-> cipher,$ cipherKey,$ data,$ this->模式,$ iv);

$ mac = hash_hmac('sha512',$ enc,$ macKey,true);
返回$ salt。 $ enc。 $ MAC;
}

/ **
*生成一组给定随机盐和主键的键
*
* @param string $ salt A随机字符串更改密钥每个加密
* @param string $ key提供的密钥加密
*
* @returns数组一个密钥数组(密钥,一个mac密钥,和a IV)
* /
protected function getKeys($ salt,$ key){
$ ivSize = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_CBC);
$ keySize = mcrypt_get_key_size(MCRYPT_BLOWFISH,MCRYPT_MODE_CBC);
$ length = 2 * $ keySize + $ ivSize;

$ key = $ this-> pbkdf2('sha512',$ key,$ salt,$ this-> rounds,$ length);

$ cipherKey = substr($ key,0,$ keySize);
$ macKey = substr($ key,$ keySize,$ keySize);
$ iv = substr($ key,2 * $ keySize);
返回数组($ cipherKey,$ macKey,$ iv);
}

/ **
*使用PBKDF2算法弹出密钥
*
* @see http://en.wikipedia.org/ wiki / PBKDF2
*
* @param string $ algo使用
* @param string的算法$ key拉伸的关键
* @param string $ salt随机盐
* @param int $ rounds导出的轮数
* @param int $ length输出键的长度
*
* @returns string派生键。
* /
protected function pbkdf2($ algo,$ key,$ salt,$ rounds,$ length){
$ size = strlen(hash($ algo,'',true)) ;
$ len = ceil($ length / $ size);
$ result =''; ($ i = 1; $ i $ = $ len; $ i ++){
$ tmp = hash_hmac($ algo,$ salt。pack('N',$ i),$ key ,真)
$ res = $ tmp;
($ j = 1; $ j <$ rounds; $ j ++){
$ tmp = hash_hmac($ algo,$ tmp,$ key,true);
$ res ^ = $ tmp;
}
$ result。= $ res;
}
返回substr($ result,0,$ length);
}

protected function pad($ data){
$ length = mcrypt_get_block_size(MCRYPT_BLOWFISH,MCRYPT_MODE_CBC);
$ padAmount = $ length - strlen($ data)%$ length;
if($ padAmount == 0){
$ padAmount = $ length;
}
返回$数据。 str_repeat(chr($ padAmount),$ padAmount);
}

protected function unpad($ data){
$ length = mcrypt_get_block_size(MCRYPT_BLOWFISH,MCRYPT_MODE_CBC);
$ last = ord($ data [strlen($ data) - 1]);
if($ last> $ length)return false;
if(substr($ data,-1 * $ last)!== str_repeat(chr($ last),$ last)){
return false;
}
return substr($ data,0,-1 * $ last);
}
}


解决方案

您的解密例程的代码适用于我:

  public function decrypt($ data,$ key){
$ salt = substr($ data,0,128);
$ enc = substr($ data,128,-64);
$ mac = substr($ data,-64);

list($ cipherKey,$ macKey,$ iv)= $ this-> getKeys($ salt,$ key);

if($ mac!== hash_hmac('sha512',$ enc,$ macKey,true)){
return false;
}

$ dec = openssl_decrypt($ enc,$ this-> cipher,$ cipherKey,OPENSSL_RAW_DATA,$ iv);

return $ dec;
}

测试:



<$
'这是一个秘密密钥'
'G906m70p(IhzA5T& 5x7(w0%a631)u)%D6E79cIYJQ!iP2U(xT13q6 )chr(3)。chr(4)。chr(192)。chr(16)。 'b


$ b $ data = [
'A',
'这是一个测试',
'现在测试用1234567890加密一点点东西',
'$ length = mcrypt_get_block_size(MCRYPT_BLOWFISH,MCRYPT_MODE_CBC); $ last = ord($ data [strlen($ data) - 1]);',
'Lorem ipsum dolor sit amet,consectetur adipiscing elit。Donec sit amet pharetra urna。Vestibulum ante ipsum primis in faucibus orci luctus et ult rices cub cub cub cub cub cub d d d d d d d d d d d d d d d d d d d d d d d d d d d d iam molestie fermentum。Pellentesque dignissim dui quis tortor eleifend,ut maximus elit egestas。 Donec posuere odio et auctor porta。 Quisque placerat mushimentum maximus。 。ur。。。。。。。。。。。。。。。。。 Mauris eget nulla nisl。',
];

$ failures = 0;

foreach($ data as $ datum){
foreach($ keys as $ key){
$ enc = new Encryption(MCRYPT_BLOWFISH,MCRYPT_MODE_CBC);

$ encrypted = $ enc-> encrypt($ datum,$ key);

$ dec = new EncryptionOpenSsl('bf-cbc');

$ decryptpted = $ dec-> decrypt($ encrypted,$ key);

if(strcmp($ datum,$ decryptpted)!== 0){
echo使用'$ datum'的键'$ key'加密失败'$ decryptpted'!= '$基准' <峰; br><峰; br> \\\
\\\
;
$ failures ++;
}
}
}

if($ failures){
echo$ failures tests failed。< br> \\\

} else {
echoALL OKAY< br> \\\
;
}

如果您可以确认它适用于您,我可以整理答案并添加最终的工作代码。


I am using the below commonly referenced library for encryption. I want to upgrade it to OpenSSL from Mcrypt so that I am no longer using a deprecated library.

I'm trying to find out if this is even possible. I've done some research on this, but I've found conflicting information:

This post says that it is impossible to decrypt data using OpenSSL that was encrypted with Mcrypt. https://stackoverflow.com/a/19748494/5834657

However, this post says that it is possible using padding. It appears that my function uses padding. Is this the right type of padding needed to make this work? https://stackoverflow.com/a/31614770/5834657

<?php 

namespace Utilities\Encryption;

/**
* A class to handle secure encryption and decryption of arbitrary data
*
* Note that this is not just straight encryption.  It also has a few other
* features in it to make the encrypted data far more secure.  Note that any
* other implementations used to decrypt data will have to do the same exact
*  operations.  
*
* Security Benefits:
*
* - Uses Key stretching
* - Hides the Initialization Vector
* - Does HMAC verification of source data
*
*/

class Encryption {

/**
 * @var string $cipher The mcrypt cipher to use for this instance
 */
protected $cipher = '';

/**
 * @var int $mode The mcrypt cipher mode to use
 */
protected $mode = '';

/**
 * @var int $rounds The number of rounds to feed into PBKDF2 for key generation
 */
protected $rounds = 100;

/**
 * Constructor!
 *
 * @param string $cipher The MCRYPT_* cypher to use for this instance
 * @param int    $mode   The MCRYPT_MODE_* mode to use for this instance
 * @param int    $rounds The number of PBKDF2 rounds to do on the key
 */
public function __construct($cipher, $mode, $rounds = 100) {
    $this->cipher = $cipher;
    $this->mode = $mode;
    $this->rounds = (int) $rounds;
}

/**
 * Decrypt the data with the provided key
 *
 * @param string $data The encrypted datat to decrypt
 * @param string $key  The key to use for decryption
 * 
 * @returns string|false The returned string if decryption is successful
 *                           false if it is not
 */
public function decrypt($data, $key) {
    $salt = substr($data, 0, 128);
    $enc = substr($data, 128, -64);
    $mac = substr($data, -64);

    list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

    if ($mac !== hash_hmac('sha512', $enc, $macKey, true)) {
         return false;
    }

    $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv);

    $data = $this->unpad($dec);

    return $data;
}

/**
 * Encrypt the supplied data using the supplied key
 * 
 * @param string $data The data to encrypt
 * @param string $key  The key to encrypt with
 *
 * @returns string The encrypted data
 */
public function encrypt($data, $key) {
    $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
    list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

    $data = $this->pad($data);

    $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv);

    $mac = hash_hmac('sha512', $enc, $macKey, true);
    return $salt . $enc . $mac;
}

/**
 * Generates a set of keys given a random salt and a master key
 *
 * @param string $salt A random string to change the keys each encryption
 * @param string $key  The supplied key to encrypt with
 *
 * @returns array An array of keys (a cipher key, a mac key, and a IV)
 */
protected function getKeys($salt, $key) {
    $ivSize = mcrypt_get_iv_size($this->cipher, $this->mode);
    $keySize = mcrypt_get_key_size($this->cipher, $this->mode);
    $length = 2 * $keySize + $ivSize;

    $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length);

    $cipherKey = substr($key, 0, $keySize);
    $macKey = substr($key, $keySize, $keySize);
    $iv = substr($key, 2 * $keySize);
    return array($cipherKey, $macKey, $iv);
}

/**
 * Stretch the key using the PBKDF2 algorithm
 *
 * @see http://en.wikipedia.org/wiki/PBKDF2
 *
 * @param string $algo   The algorithm to use
 * @param string $key    The key to stretch
 * @param string $salt   A random salt
 * @param int    $rounds The number of rounds to derive
 * @param int    $length The length of the output key
 *
 * @returns string The derived key.
 */
protected function pbkdf2($algo, $key, $salt, $rounds, $length) {
    $size   = strlen(hash($algo, '', true));
    $len    = ceil($length / $size);
    $result = '';
    for ($i = 1; $i <= $len; $i++) {
        $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true);
        $res = $tmp;
        for ($j = 1; $j < $rounds; $j++) {
             $tmp  = hash_hmac($algo, $tmp, $key, true);
             $res ^= $tmp;
        }
        $result .= $res;
    }
    return substr($result, 0, $length);
}

protected function pad($data) {
    $length = mcrypt_get_block_size($this->cipher, $this->mode);
    $padAmount = $length - strlen($data) % $length;
    if ($padAmount == 0) {
        $padAmount = $length;
    }
    return $data . str_repeat(chr($padAmount), $padAmount);
}

protected function unpad($data) {
    $length = mcrypt_get_block_size($this->cipher, $this->mode);
    $last = ord($data[strlen($data) - 1]);
    if ($last > $length) return false;
    if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) {
        return false;
    }
    return substr($data, 0, -1 * $last);
 }
}


Update: I have been trying to decrypt a string encrypted with Mcrypt using OpenSSL by converting the library to OpenSSL.

Then, I'm encrypting a string using a key using the above code, and trying to decrypt that value using the below code and the same key. However I'm just getting a blank response. If I comment out:

$data = $this->unpad($dec)

in the decrypt function I get a string but it is just jumbled up characters (Much like it looks when it's first encrypted.)

<?php 

namespace Utilities\Encryption;

/**
* A class to handle secure encryption and decryption of arbitrary data
*
* Note that this is not just straight encryption.  It also has a few other
*  features in it to make the encrypted data far more secure.  Note that any
*  other implementations used to decrypt data will have to do the same exact
*  operations.  
*
* Security Benefits:
*
* - Uses Key stretching
* - Hides the Initialization Vector
* - Does HMAC verification of source data
*
*/
class EncryptionOpenSsl {

/**
 * @var string $cipher The mcrypt cipher to use for this instance
 */
protected $cipher = '';

/**
 * @var int $mode The mcrypt cipher mode to use
 */
protected $mode = '';

/**
 * @var int $rounds The number of rounds to feed into PBKDF2 for key generation
 */
protected $rounds = 100;

/**
 * Constructor!
 *
 * @param string $cipher The MCRYPT_* cypher to use for this instance
 * @param int    $mode   The MCRYPT_MODE_* mode to use for this instance
 * @param int    $rounds The number of PBKDF2 rounds to do on the key
 */
public function __construct($cipher, $rounds = 100) {
    $this->cipher = $cipher;
    // $this->mode = MCRYPT_MODE_CBC;
    $this->rounds = (int) $rounds;
}

/**
 * Decrypt the data with the provided key
 *
 * @param string $data The encrypted datat to decrypt
 * @param string $key  The key to use for decryption
 * 
 * @returns string|false The returned string if decryption is successful
 *                           false if it is not
 */
public function decrypt($data, $key) {
    $salt = substr($data, 0, 128);
    $enc = substr($data, 128, -64);
    $mac = substr($data, -64);

    list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

    if ($mac !== hash_hmac('sha512', $enc, $macKey, true)) {
         return false;
    }
    $dec = openssl_decrypt($enc, $this->cipher, $key, OPENSSL_RAW_DATA, $iv);
    // $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv);

    $data = $this->unpad($dec);

    return $data;
}

/**
 * Encrypt the supplied data using the supplied key
 * 
 * @param string $data The data to encrypt
 * @param string $key  The key to encrypt with
 *
 * @returns string The encrypted data
 */
public function encrypt($data, $key) {
    $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
    list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

    $data = $this->pad($data);

    $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv);

    $mac = hash_hmac('sha512', $enc, $macKey, true);
    return $salt . $enc . $mac;
}

/**
 * Generates a set of keys given a random salt and a master key
 *
 * @param string $salt A random string to change the keys each encryption
 * @param string $key  The supplied key to encrypt with
 *
 * @returns array An array of keys (a cipher key, a mac key, and a IV)
 */
protected function getKeys($salt, $key) {
    $ivSize = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
    $keySize = mcrypt_get_key_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
    $length = 2 * $keySize + $ivSize;

    $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length);

    $cipherKey = substr($key, 0, $keySize);
    $macKey = substr($key, $keySize, $keySize);
    $iv = substr($key, 2 * $keySize);
    return array($cipherKey, $macKey, $iv);
}

/**
 * Stretch the key using the PBKDF2 algorithm
 *
 * @see http://en.wikipedia.org/wiki/PBKDF2
 *
 * @param string $algo   The algorithm to use
 * @param string $key    The key to stretch
 * @param string $salt   A random salt
 * @param int    $rounds The number of rounds to derive
 * @param int    $length The length of the output key
 *
 * @returns string The derived key.
 */
protected function pbkdf2($algo, $key, $salt, $rounds, $length) {
    $size   = strlen(hash($algo, '', true));
    $len    = ceil($length / $size);
    $result = '';
    for ($i = 1; $i <= $len; $i++) {
        $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true);
        $res = $tmp;
        for ($j = 1; $j < $rounds; $j++) {
             $tmp  = hash_hmac($algo, $tmp, $key, true);
             $res ^= $tmp;
        }
        $result .= $res;
    }
    return substr($result, 0, $length);
}

protected function pad($data) {
    $length = mcrypt_get_block_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
    $padAmount = $length - strlen($data) % $length;
    if ($padAmount == 0) {
        $padAmount = $length;
    }
    return $data . str_repeat(chr($padAmount), $padAmount);
}

protected function unpad($data) {
    $length = mcrypt_get_block_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
    $last = ord($data[strlen($data) - 1]);
    if ($last > $length) return false;
    if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) {
        return false;
    }
    return substr($data, 0, -1 * $last);
 }
}

解决方案

This code for your decryption routine works for me:

public function decrypt($data, $key) {
    $salt = substr($data, 0, 128);
    $enc = substr($data, 128, -64);
    $mac = substr($data, -64);

    list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

    if ($mac !== hash_hmac('sha512', $enc, $macKey, true)) {
         return false;
    }

    $dec = openssl_decrypt($enc, $this->cipher, $cipherKey, OPENSSL_RAW_DATA, $iv);

    return $dec;
}

Test:

$keys = [
    'this is a secret key.',
    'G906m70p(IhzA5T&5x7(w0%a631)u)%D6E79cIYJQ!iP2U(xT13q6)tJ6gZ3D2wi&0")7cP5',
    chr(6) . chr(200) . chr(16) . 'my key ' . chr(3) . chr(4) . chr(192) . chr(254) . ' zyx0987!!',
    'and finally one more key to test with here:',
];


$data = [
    'A',
    'This is a test',
    'now test encrypting something a little bit longer with 1234567890.',
    '$length = mcrypt_get_block_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC); $last = ord($data[strlen($data) - 1]);',
    'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sit amet pharetra urna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut fringilla, quam sed eleifend eleifend, justo turpis consectetur tellus, quis tristique eros erat at nibh. Nunc dictum neque vel diam molestie fermentum. Pellentesque dignissim dui quis tortor eleifend, ut maximus elit egestas. Donec posuere odio et auctor porta. Quisque placerat condimentum maximus. Curabitur luctus dolor eget sem luctus, in dignissim tortor venenatis. Mauris eget nulla nisl.',
];

$failures = 0;

foreach ($data as $datum) {
    foreach ($keys as $key) {
        $enc = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);

        $encrypted = $enc->encrypt($datum, $key);

        $dec = new EncryptionOpenSsl('bf-cbc');

        $decrypted = $dec->decrypt($encrypted, $key);

        if (strcmp($datum, $decrypted) !== 0) {
            echo "Encryption with key '$key' of '$datum' failed.  '$decrypted' != '$datum'<br><br>\n\n";
            $failures++;
        }
    }
}

if ($failures) {
    echo "$failures tests failed.<br>\n";
} else {
    echo "ALL OKAY<br>\n";
}

If you can confirm it works for you as well I can tidy up the answer and add final working code.

这篇关于将我的加密库从Mcrypt升级到OpenSSL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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