mcrypt到OpenSSL迁移的一些注意事项

不同语言产生加密差异的原因

不同语言产生不同加密结果差异的主要原因基本上产生在算法选择、填充方式、$IV量这几方面的差异

具体可以看这篇文章:https://segmentfault.com/a/1190000018059273 文章里面有个错误 我已经在评论里面指出。

但是其他方面总结的非常全面:

MCRYPT_RIJNDAEL_256 并不是 AES-256

openssl_* 的 AES cipher 的 iv 长度 固定 为 16 位

这一点 很多网上抄写的代码基本上都用mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128 , MCRYPT_MODE_CBC) 来获取iv长度,这个函数返回的就是16,与OPENSSL兼容

MCRYPT_*默认的填充方式不是PKCS7,而是填充null('\x00')

常见的对方语言比如java/.net则默认使用PKCS7,所以存在实现差异,也会导致加密的结果不一致

所以,如果你的MCRYPT_*实现的AES加密符合$iv=16,使用PKCS7填充,算法和$key 长度也符合要求,那么就能实现100%兼容的转换。

转换过程

转换填充方式

常见的网上流行的代码 基本上都有用纯PHP实现了类似这样的PKCS7填充方式

在OPENSSL下请忽略他,因为默认就是PKCS7填充

转换$iv生成方法

OPENSSL本身实现了一个openssl_random_pseudo_bytes来作为推荐的$iv生成方法,记得生成16位的就行,如果你不生成$iv,那么解密也不需要使用$iv

确定加密方式

参考上面那个表里面根据$key长度确定到底使用的是AES-128、256等加密方法

注意加密的编码方式

OPENSSL有OPENSSL_RAW_DATA等选项控制输入输出原始字符串还是编码后base64文本,你需要自行确认加密解密实际输入输出的参数应该是哪种形式,尤其是需要和$iv一起传递密文的时候

传输加密后文本

如果你没有使用$iv,那么加密后的内容就是全部,按需要进行传输就行,如果你使用$iv,那么需要把这个$iv一起传递给对方,有些实现是,把$iv拼在加密后的原始字符串前后,解密的时候按照固定长度切出密文和$iv,这个可以依据双方的系统设计,自行确定适配方法。

Author Info :
  • From:mcrypt到OpenSSL迁移的一些注意事项
  • URL:https://blog.ihipop.com/2020/09/5277.html
  • Please Reserve This Link,Thanks!
  • 发表回复

    您的电子邮箱地址不会被公开。 必填项已用 * 标注