RSA-openresty、php、分段加密、明文过长

PHP公钥加密:

 1 <?php
 2 $pubKey = <<<EOF
 3 -----BEGIN PUBLIC KEY-----
 4 ... 这里是示意...
 5 -----END PUBLIC KEY-----
 6 EOF;
 7 $pubKey = openssl_pkey_get_public($pubKey);
 8 $part_len = openssl_pkey_get_details($pubKey)['bits'] / 8 - 11; // 如果明文过长,加密时候需要分段; 因为明文长度必须比 RSA 钥模长(modulus) 短至少11个字节, 也就是 RSA_size(rsa) – 11
 9 if (!$pubKey) {
10     echo 'pubKey Error';
11     exit(0);
12 }
13 $data = <<<EOF
14 码农
15 EOF;
16 
17 $a = microtime(true) * 1000;
18 $parts = str_split($data, $part_len);
19 foreach ($parts as $part) {
20     $encrypted_temp = '';
21     openssl_public_encrypt($part, $encrypted_temp, $pubKey);
22     $encrypted .= $encrypted_temp;
23 }
24 $encrypted = base64_encode($encrypted);
25 $b = microtime(true) * 1000;
26 echo $encrypted;
27 echo $b - $a, PHP_EOL;

Lua(OpenResty)私钥解密:

 1 local decrypt = function()
 2     local rsa_priv_key = [[
 3 -----BEGIN PRIVATE KEY-----
 4 ... 这里是示意...
 5 -----END PRIVATE KEY-----
 6     ]]
 7 
 8     local encrypted = "密文"
 9     encrypted = ngx.decode_base64(encrypted)
10     if not encrypted then
11         return nil, "Base64 decode err"
12     end
13 
14     -- lua-resty-rsa https://github.com/spacewander/lua-resty-rsa
15     -- 注意直接opm install spacewander/lua-resty-rsa 有问题 需要github上直接下载然后替换
16     local priv, err = resty_rsa:new({ private_key = rsa_priv_key})
17     if not priv then
18         return nil, "new rsa err: " .. err
19     end
20     local chunkSize = 2048 / 8; -- 2048 为密钥长度 因为公钥加密后 长度都跟密钥长度一致
21     local decrypted = ''
22     for i = 1, #encrypted, chunkSize do
23         sub_encrypted = encrypted:sub(i, i + chunkSize - 1)
24         decrypted = decrypted .. priv:decrypt(sub_encrypted)
25     end
26     return decrypted, nil
27 end

RSA加密填充方式:
RSA_PKCS1_PADDING, -- RSA_size - 11 必须 比 RSA 钥模长(modulus) 短至少11个字节 

如果你的明文不够128字节

加密的时候会在你的明文中随机填充一些数据,所以会导致对同样的明文每次加密后的结果都不一样。

对加密后的密文,服务器使用相同的填充方式都能解密。解密后的明文也就是之前加密的明文。

RSA_SSLV23_PADDING, -- RSA_size - 11 必须 比 RSA 钥模长(modulus) 短至少11个字节

RSA_NO_PADDING, -- RSA_size 可以和RSA钥模长一样长,如果输入的明文过长,必须切割, 然后填充 加密的时候会在你的明文前面,前向填充零。解密后的明文也会包括前面填充的零,这是服务器需要注意把解密后的字段前向填充的

RSA_PKCS1_OAEP_PADDING, -- RSA_size - 42 or RSA_size(rsa) – 41

总结:

  • 在不同的padding模式下,使用相同长度的密钥可以加密的数据最大长度不同;
  • 在不同密钥长度下,使用相同的padding模式可以加密的数据最大长度也不同;

原文地址:https://www.cnblogs.com/sanshuiqing/p/14475635.html