邮储银行php对接加解密,PHP加解密算法使用 openssl 替换 mcrypt 扩展的一个小坑

由于 PHP 7.2 不再支持 mcrypt,因此需要将 mcrypt 替换为 openssl。

但是在替换发现,php 的 openssl 和 mcrypt 实现有一些不同,有几个坑需要注意。

mcrypt 中的 RIJNDAEL_128 算法是 AES 算法的超集,RIJNDAEL_128 的 128 指的是 Block Size,而 AES-128 中的 128 是 Key Size。因此,同是 RIJNDAEL_128 算法,如果你使用的 Key 是 128 位的(16 个字符)那就等同 AES-128。如果 Key 是 192 位的(24 个字符),那就等同与 AES-192。如果 Key 是 256 位的(32 个字符),则等同与 AES-256

如果使用 RIJNDAEL_256,则无法对应到 AES 算法。因为 AES 固定了 Block Size 是 128,没有 256 的选择

php 的 openssl 实现的 AES 算法,只有 PKCS#7 padding 和 no padding 两个选择,而 mcrypt 默认是 zero padding。因此,如果原先没有手动处理 padding,则切换到 openssl 的时候需要启用 no padding 并手动处理 padding。

一些函数的替换:mcrypt_get_iv_size  替换为 openssl_cipher_iv_length ,mcrypt_create_iv  替换为 openssl_random_pseudo_bytes 。

修改前后代码如下:<?php

define('ENCRYPT_METHOD', 'AES-256-CBC');

define('IV_SIZE', openssl_cipher_iv_length(ENCRYPT_METHOD));

function encrypt_mcrypt($payload, $key)

{

// 初始化 IV

$iv = openssl_random_pseudo_bytes(IV_SIZE);

// 调用加密

$crypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $payload, MCRYPT_MODE_CBC, $iv);

// 拼接 IV 和 密文

$combo = $iv . $crypt;

// 编码拼接后的密文

$garble = base64_encode($combo);

return $garble;

}

function decrypt_mcrypt($garble, $key)

{

// 解码密文

$combo = base64_decode($garble);

// 根据 IV SIZE 提取 IV

$iv = substr($combo, 0, IV_SIZE);

// 获取剩余密文

$crypt = substr($combo, IV_SIZE);

// 解密

$payload = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $crypt, MCRYPT_MODE_CBC, $iv);

return $payload;

}

function encrypt_openssl($payload, $key)

{

// 初始化 IV

$iv = openssl_random_pseudo_bytes(IV_SIZE);

// 对密文进行 padding, 16 = 128 / 8

if (strlen($payload) % 16) {

$payload = str_pad(

$payload,

strlen($payload) + 16 - strlen($payload) % 16,

"\0"

);

}

// 加密

$encryptedMessage = openssl_encrypt($payload, ENCRYPT_METHOD, $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);

// 编码,拼接 IV

return base64_encode($iv . $encryptedMessage);

}

function decrypt_openssl($garble, $key)

{

// 解码密文

$raw = base64_decode($garble);

// 根据 IV SIZE 提取 IV

$iv = substr($raw, 0, IV_SIZE);

// 获取剩余密文

$data = substr($raw, IV_SIZE);

// 解密

return openssl_decrypt($data, ENCRYPT_METHOD, $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);

}

$key = md5("password");

echo (decrypt_openssl(encrypt_mcrypt("4db8c44de8f16b4f0c39ef3b38d47c6bdd000082b3b628ee25c20b308d02cf29", $key), $key) . "\n");

echo (decrypt_mcrypt(encrypt_openssl("4db8c44de8f16b4f0c39ef3b38d47c6bdd000082b3b628ee25c20b308d02cf29", $key), $key) . "\n");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值