PHP使用RSA加解密需要注意的几个问题

使用RSA做加解密有过几次经历,每次掉的坑都不太一样。这里把遇到的问题表述一下,以备下次查阅。

  • PHP56+
  • openssl扩展

一、私钥加密公钥解密

RSA非对称加密:私钥加密请使用公钥解密,公钥加密请使用私钥解密。

二、加密模式和填充方法

首先要和对方核实加密模式和填充方法,PHP中RSA 私钥加密默认使用OPENSSL_PKCS1_PADDING填充,可设置为 OPENSSL_NO_PADDING ,其他加解密具体填充模式可参考PHP官方文档。

三、加密数据长度要求

以私钥加密为例,加密强度1024的私钥,每次可加密数据长度为 1024位/8=128字节,当使用OPENSSL_PKCS1_PADDING(这个要占用11个字节)填充时,可加密128-11=117字节。如果超出,那么这些openssl加解密函数会返回false。所以当超出时,请分段加密!

注:当然对方也可能是64字节进行分段加密,需要和对方核实并保持一致。

四、注意加解密前进行编码和解码

一般来说加密后的数据是二进制数据,为了便于传输和可见性,通常会将加密后的数据进行base64编码。同样地,解密前需将密文进行base64解码。

注:需和对方核实,此处有可能使用2进制、16进制编码、解码,如bin2hex、hex2bin

五、示例

这里以RSA私钥加密为例,写一个demo,公钥解密、公钥加密以及私钥解密同理,请更换相应openssl_*簇加解密函数即可。

$ourSecret = 'this is ok.'; // 待加密文本
$pem = 'your_pem_format.file'; // 注意这里是pem格式的文件内容
$pi_key = openssl_pkey_get_private($pem);
if (!$pi_key) die('$pem Format Error.');

// ras 加密时最大长度117字符串,因此加密时要循环切割&加密拼接(这里假设超出了117字符)
// 对方Java源码可能使用64位切割
$rsaContent = '';
foreach (str_split($ourSecret, 117) as $chunk) {
    $rsaEn = openssl_private_encrypt($chunk, $encrypted, $pi_key); // 私钥加密
    if (!$rsaEn) dump('RSA Encrypt Error.');
    $rsaContent .= $encrypted;
}

if (!$rsaContent) die('RSA Encrypt Fail.');
$rsaContent = base64_encode($rsaContent); // 进行base64编码

echo 'RSA加密结果:',$rsaContent;
参考链接:
https://secure.php.net/manual/zh/function.openssl-private-encrypt.php
https://www.felix021.com/blog/read.php?2169
https://www.cnblogs.com/firstForEver/p/5803940.html
Author: thinkwei

发表回复

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