上一篇搞定了openresty与java之间的aes加解密。这一篇就来说说openresty与java之间RSA的加解密。在测试的过程中、发现了与aes同样的问题、就是openresty支持的填充模式不够多。关于这一点可以直接使用C语言实现一份、在通过ffi调用C的api进行加解密。不过我不会C语言......而且好像使用C来做也是特别的麻烦。所以就只能修改java了、让Java使用openresty支持的填充方式。openresty模式的包里面是没有rsa支持的。需要去下载一份、下载地址:GitHub - spacewander/lua-resty-rsa: RSA encrypt/decrypt & sign/verify for OpenResty/LuaJIT下载回来后、我们将他放在openresty的lualib\resty目录下。就可以在程序中使用了。

密钥对格式

上面的实现中、密钥的格式是根据初始化参数进行区分的。

public_key, private_key, err = rsa:generate_rsa_keys(bits, in_pkcs8_fmt)

当in_pkcs8_fmt等于true(PKCS#8格式)的时候公私玥的格式如下:

-----BEGIN PUBLIC KEY-----

.........我是公钥.........

-----END PUBLIC KEY-----

-----BEGIN PRIVATE KEY-----

.........我是私钥.........

-----END PRIVATE KEY-----

当in_pkcs8_fmt等于false(PKCS#1格式)的时候公私玥的格式如下:

-----BEGIN RSA PUBLIC KEY-----

.........我是公钥.........

-----END RSA PUBLIC KEY-----

-----BEGIN RSA PRIVATE KEY-----

.........我是私钥.........

-----END RSA PRIVATE KEY-----

默认in_pkcs8_fmt是等于false的。这里我们使用没有RSA的、也就是in_pkcs8_fmt等于true。

填充方式

openresty的填充方式在git的文档中、没有明确的描述出来。这里我们可以直接打开rsa.lua文件查看。源代码里面的填充方式如下:

RSA_PKCS1_PADDING = 1,  -- RSA_size - 11
RSA_SSLV23_PADDING = 2, -- RSA_size - 11
RSA_NO_PADDING = 3,     -- RSA_size
RSA_PKCS1_OAEP_PADDING = 4, -- RSA_size - 42

openresty rsa填充方式与java的对应

openresty = java

RSA_PKCS1_PADDING = RSA/ECB/PKCS1Padding
RSA_SSLV23_PADDING = 未知
RSA_NO_PADDING = RSA/NONE/NoPadding
RSA_PKCS1_OAEP_PADDING = RSA/ECB/OAEPWithSHA-1AndMGF1PADDING

需要注意的是、RSA_NO_PADDING的方式,Java自带的加解密包是不支持的、又需要用到之前AES那边用到的bouncycastle的包来进行加解密操作。

Security.addProvider(new BouncyCastleProvider());Cipher.getInstance("RSA/NONE/NoPadding")

这里我们使用RSA_PKCS1_OAEP_PADDING = RSA/ECB/OAEPWithSHA-1AndMGF1PADDING来进行填充。Java是RSA/ECB/OAEPWithSHA-1AndMGF1PADDING而openresty是RSA_PKCS1_OAEP_PADDING。

代码

javaRSA代码

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;
import java.util.HashMap;
import java.util.Map;/*** RSA处理工具类** @author hhs* @date 2019-10-22 09:54* @since JDK1.8*/
@Slf4j
public class RSAStaticUtils {/*** 填充模式*/private final static String RSA_CIPHER = "RSA/ECB/OAEPWithSHA-1AndMGF1PADDING";//private final static String RSA_CIPHER = "RSA/None/NoPadding";//private final static String RSA_CIPHER = "RSA/ECB/PKCS1Padding";/*** 密钥位数*/private static final int KEY_SIZE = 2048;private static KeyPair KEY_PAIR;static{try {SecureRandom random = new SecureRandom();KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");generator.initialize(KEY_SIZE, random);KEY_PAIR = generator.generateKeyPair();} catch (Exception e) {throw new RuntimeException(e);}}/*** 生成rsa公钥和私钥** @return Map {@link HashMap}: publicKey-公钥(RSAPublicKey),privateKey-私钥(RSAPrivateKey)* @author hhs* @date 2019-10-22 09:54*/public static Map<String, Object> getRsaKey() {Map<String, Object> keyInfo = new HashMap<>(2);// 公钥RSAPublicKey publicKey = (RSAPublicKey) KEY_PAIR.getPublic();keyInfo.put("publicKey", publicKey);// 私钥RSAPrivateKey privateKey = (RSAPrivateKey) KEY_PAIR.getPrivate();keyInfo.put("privateKey", privateKey);return keyInfo;}/*** 生成rsa公钥和私钥** @return Map {@link HashMap}: publicKey-公钥(X509格式),privateKey-私钥(PKCS8格式)* @author hhs* @date 2019-10-22 09:54*/public static Map<String, String> getX509AndPKCS8Key() {Map<String, Object> keyInfo = getRsaKey();Map<String, String> x509AndPKCS8Key = new HashMap<>(2);// 公钥RSAPublicKey publicKey = (RSAPublicKey) keyInfo.get("publicKey");
//        String rsaPublicKey = (new BASE64Encoder()).encodeBuffer(publicKey.getEncoded());String rsaPublicKey = Base64.encodeBase64String(publicKey.getEncoded());x509AndPKCS8Key.put("publicKey", rsaPublicKey);// 私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyInfo.get("privateKey");
//        String rsaPrivateKey = (new BASE64Encoder()).encodeBuffer(privateKey.getEncoded());String rsaPrivateKey = Base64.encodeBase64String(privateKey.getEncoded());x509AndPKCS8Key.put("privateKey", rsaPrivateKey);return x509AndPKCS8Key;}/*** PKCS8的私钥字符串还原为RSA私钥** @param pkcs8Key {@link String} 待还原私钥字符串* @return RSAPrivateKey {@link RSAPrivateKey}* @author hhs* @date 2019-10-22 09:54*/private static RSAPrivateKey getPrivateKey(String pkcs8Key) {PrivateKey privateKey = null;try {
//            byte[] decodeKey = (new BASE64Decoder()).decodeBuffer(pkcs8Key);byte[] decodeKey = Base64.decodeBase64(pkcs8Key);PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(decodeKey);KeyFactory keyFactory = KeyFactory.getInstance("RSA");privateKey = keyFactory.generatePrivate(pkcs8);} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {log.error("----------RSAUtils---------->PKCS8的私钥字符串还原为RSA私钥出错:{}", e.getMessage());}return (RSAPrivateKey) privateKey;}/*** X509的公钥字符串还原为RSA公钥** @param x509Key {@link String} 待还原公钥字符串* @return RSAPublicKey {@link RSAPublicKey}* @author hhs* @date 2019-10-22 09:54*/private static RSAPublicKey getPublicKey(String x509Key) {PublicKey publicKey = null;try {
//            byte[] decodeKey = (new BASE64Decoder()).decodeBuffer(x509Key);byte[] decodeKey = Base64.decodeBase64(x509Key);X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodeKey);KeyFactory keyFactory = KeyFactory.getInstance("RSA");publicKey = keyFactory.generatePublic(x509);} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {log.error("----------RSAUtils---------->X509的公钥字符串还原为RSA公钥:{}", e.getMessage());}return (RSAPublicKey) publicKey;}/*** <p>使用模和指数生成RSA公钥* </p>** @param modulus        {@link BigInteger} 模* @param publicExponent {@link BigInteger} 公钥指数* @return RSAPublicKey {@link RSAPublicKey}* @author hhs* @date 2019-10-22 09:54*/public static RSAPublicKey getPublicKey(BigInteger modulus, BigInteger publicExponent) {RSAPublicKey publicKey = null;try {KeyFactory keyFactory = KeyFactory.getInstance("RSA");RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, publicExponent);publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);log.info("----------RSAUtils---------->生成公钥:{}", publicKey);} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {log.error("----------RSAUtils---------->生成公钥异常:{}", e.getMessage());}return publicKey;}/*** <p>* 使用模和指数生成RSA私钥* </p>** @param modulus         {@link BigInteger} 模* @param privateExponent {@link BigInteger} 私钥指数* @return RSAPrivateKey {@link RSAPrivateKey}* @author hhs* @date 2019-10-22 09:54*/public static RSAPrivateKey getPrivateKey(BigInteger modulus, BigInteger privateExponent) {RSAPrivateKey privateKey = null;try {KeyFactory keyFactory = KeyFactory.getInstance("RSA");RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulus, privateExponent);privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);} catch (Exception e) {log.error("----------RSAUtils---------->生成私钥异常:{}", e.getMessage());}return privateKey;}/*** 公钥加密** @param publicKey {@link String} X509格式公钥* @param plaintext {@link String} 明文* @return String {@link String} 密文* @author hhs* @date 2019-10-22 09:54*/public static String encryptPublicKey(String publicKey, String plaintext) {RSAPublicKey rsaPublicKey = getPublicKey(publicKey);String result = "";try {byte[] bytes = encryptByRsaKey(rsaPublicKey, plaintext.getBytes());result = Base64.encodeBase64String(bytes);} catch (Exception e) {log.error("----------RSAUtils---------->公钥加密异常:{}", e.getMessage());}return result;}/*** 公钥解密** @param publicKey  {@link String} X509格式公钥* @param ciphertext {@link String} 密文* @return String {@link String} 明文* @author hhs* @date 2019-10-22 09:54*/public static String decryptPublicKey(String publicKey, String ciphertext) {byte[] bytes = Base64.decodeBase64(ciphertext);RSAPublicKey rsaPublicKey = getPublicKey(publicKey);String result = "";try {result = new String(decryptByRsaKey(rsaPublicKey, bytes), StandardCharsets.UTF_8);} catch (Exception e) {log.error("----------RSAUtils---------->私钥解密异常:{}", e.getMessage());}return result;}/*** 私钥加密** @param privateKey {@link String} PKCS8格式私钥* @param plaintext  {@link String} 明文* @return String {@link String} 密文* @author hhs* @date 2019-10-22 09:54*/public static String encryptPrivateKey(String privateKey, String plaintext) {RSAPrivateKey rsaPrivateKey = getPrivateKey(privateKey);String result = "";try {byte[] bytes = encryptByRsaKey(rsaPrivateKey, plaintext.getBytes());result = Base64.encodeBase64String(bytes);} catch (Exception e) {log.error("----------RSAUtils---------->公钥加密异常:{}", e.getMessage());}return result;}/*** 私钥解密** @param privateKey {@link String} PKCS8格式私钥* @param ciphertext {@link String} 密文* @return String {@link String}* @author hhs* @date 2019-10-22 09:54*/public static String decryptPrivateKey(String privateKey, String ciphertext) {byte[] bytes = Base64.decodeBase64(ciphertext);RSAPrivateKey rsaPrivateKey = getPrivateKey(privateKey);String result = "";try {result = new String(decryptByRsaKey(rsaPrivateKey, bytes), StandardCharsets.UTF_8);} catch (Exception e) {log.error("----------RSAUtils---------->私钥解密异常:{}", e.getMessage());}return result;}/*** 数据分组解密** @param key                 {@link Key} RSA公钥或者私钥* @param ciphertext-密文byte数组* @return byte[] 明文byte数组* @throws Exception {@link Exception} 异常数据* @author hhs* @date 2019-10-22 09:54*/private static byte[] decryptByRsaKey(Key key, byte[] ciphertext) throws Exception {// Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");Cipher cipher = Cipher.getInstance(RSA_CIPHER);cipher.init(2, key);int inputLen = ciphertext.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;for (int i = 0; inputLen - offSet > 0; offSet = i * 256) {byte[] cache;if (inputLen - offSet > 256) {cache = cipher.doFinal(ciphertext, offSet, 256);} else {cache = cipher.doFinal(ciphertext, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);++i;}byte[] decryptedData = out.toByteArray();out.close();return decryptedData;}/*** 数据分组加密** @param key                {@link Key} Rsa公钥或私钥* @param plaintext-明文byte数组* @return byte[] 密文byte数组* @throws Exception {@link Exception} 异常数据* @author hhs* @date 2019-10-22 09:54*/private static byte[] encryptByRsaKey(Key key, byte[] plaintext) throws Exception {// Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");Cipher cipher = Cipher.getInstance(RSA_CIPHER);cipher.init(1, key);int inputLen = plaintext.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;for (int i = 0; inputLen - offSet > 0; offSet = i * 244) {byte[] cache;if (inputLen - offSet > 244) {cache = cipher.doFinal(plaintext, offSet, 244);} else {cache = cipher.doFinal(plaintext, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);++i;}byte[] encryptedData = out.toByteArray();out.close();return encryptedData;}
}

java加密代码运行

------------RSA------公钥加密------>main:Z7W7qJhA+rj/qxDkT3Yr3u6GkoAg88q9Ct5IurQUdwqEJGrBx172Pez8js1mnpekiFljdkhb96+JyKi8odhIXkNGEFMcSYoLBFxyQK3wzcpdzm1RXEvmSHmGLsgMTebWlIFiZnfC7PnKaxS3EF/omHmYt9IQBEqN6XAHVE6IB9K4TPGvoraPGbzJqdMr4D6CYZ2KsKKgdyjBOUJMN9UrKCvcuruXwknOXV4i8R46XwM9g8YcAH8Hfmujo07YDVicxy5dWTS3/M56zzSbeTIv67lENeiSSygtKAcrIZF+dRM6NAULckoyPAsD7SWX68AGql4dxS1fQw7EpWZTRvkaMA==
------------RSA------私钥解密------>main:6zUwU5McVrZdkKMs@vpgmUFeRd9Ms5o7G

openresty代码

local resty_rsa = require "resty.rsa"
local rsa_public_key, rsa_priv_key, err = resty_rsa:generate_rsa_keys(2048,true)
if not rsa_public_key thenngx.say('generate rsa keys err: ', err)
endngx.say(rsa_public_key)
--[[
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA72UGQ44wWYnwOdYaW8e9
LptSiRxrToCruf8PNXUKHfFdaT9ajaEGaz4onm4K8472MonFPcRvxdLHAW/Yqx74
tegZsiFGmCnA9cLIv0QqXJYDxUBbgvPWaalxgVDKQ+JZkTB9fzYKyZxqFXJtxw1O
jT59RelWCFW+bQrIJxQT5jXXwYRgzqnn3Zl9oVsu0jnckeZncHsbg3LZEh/xzU9z
upvXz2WXGBQfjeVop8NGsqGX42sYOkuEMj63aiEoJBBRpk9khxW2WtByZ9LtVTp+
rgf66JUo79G4JPpvC/Gu1DjZvmAD8v4U5J0cd3M2nvKyorZQae15FSS8dJ+IN9AS
8wIDAQAB
-----END PUBLIC KEY-----
]]--ngx.say(rsa_priv_key)
--[[
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvZQZDjjBZifA5
1hpbx70um1KJHGtOgKu5/w81dQod8V1pP1qNoQZrPiiebgrzjvYyicU9xG/F0scB
b9irHvi16BmyIUaYKcD1wsi/RCpclgPFQFuC89ZpqXGBUMpD4lmRMH1/NgrJnGoV
cm3HDU6NPn1F6VYIVb5tCsgnFBPmNdfBhGDOqefdmX2hWy7SOdyR5mdwexuDctkS
H/HNT3O6m9fPZZcYFB+N5Winw0ayoZfjaxg6S4QyPrdqISgkEFGmT2SHFbZa0HJn
0u1VOn6uB/rolSjv0bgk+m8L8a7UONm+YAPy/hTknRx3czae8rKitlBp7XkVJLx0
n4g30BLzAgMBAAECggEAVfCXchMOamZpdenVppMq6BtcYtpv70uj2m6lIBS3IA6w
8QKMWIGxEzjKTi3FArCU04m/5C+rzIGhbXOgfbXtpSgAaYEmnaOHoPJfLMKkzn4Q
NnSnJXixxVbN55WANyR/8O5ObyeQcdYUA0UEAcxWIcCIKlvcxbs6VFzlg5niluaV
n3D5l136n/5SBrRkIfSdw1MJ6faMNLu0YbIWKQIXlvrDsX4XN5f0PBT8yB+WGWAg
keCttpvWC3rtzjx46jR7EsXCYNhZKmNKulaJlUTiTGAFY6A8sEtJIfw/8/3TB6+v
6Po3SbchLgcuN5fD5DHXnU6NH66t+VDRsW0Zbsg96QKBgQD6d7Qu41lHuA+Q2USX
v90oAcO8Qyq8aI8ZoNot94BINXCukJ8kngOcsBD/WaW1A8xYdzXL7eWbL8F2riqF
dv41f0fsrFkr40tpm1YqbmUWmzctcllQeR5dgE0HMaJUAnkbw3PrkbD2bJRrKb+b
k2ziiXeW8md4umq6M/irxWM6VwKBgQD0rrUUMvuOnhHJTEoMdtzjTxccPh7Iz+BO
4kSPCftA91GK2JUEdhdNiaw6l1/BqH9rCL3AbfBHOdHtNYCgzBEViLMrqIXq5e+t
zdVuseGLLx0rN6ZQWJT68N+nxAy1K6moaBSJloQoJr+DsT4CFvCc9Kv6IX0VJfSX
tn8dK0yCxQKBgQD2pVRpa/aqWoXxlRMoAIdvczVmOhpmiOyKR00zQOwxr3Z0YPRm
obha30MNwiEdPU1IvLPcSzv08zUnguFaptA0rE+OsDXrsxu7Nn3GsQmZFmZiuZ1c
UrllSAgSkn0RD5Jllbacfs7uDASn9ue585ahCtAadEESsTiSfsVdmbZaZwKBgQCy
dhqsuOKxiqj+YR5BKRDC2hTJDKX3YWcBIhdPHMCdCcX3tzA5KMimTRvJQE8fOH52
2tFLYOQ3jvyGPteqcCylwCauWSQTx9GguthI/IS8t4hW1SgAwhsnTDhUbLG4EjiU
FBWmpJmPj3Nv4f6QF5s3X11v+qz4l85mOT1NUR9k4QKBgH648Hcr42+Rw0OcvsHJ
5ebtKa0mRdyNTiPkLAQytEc77LpC/mr6ATolIxbgRIxjroF3Ek8gG/QBLyzrLCv0
GYm0u3byqMgZYvU+RkQYIXJCwGzqPBz3+EP915DTT7a8K+tbSKRz1HxzDlbobqE2
ukG/GgeKUY4IN69lt4/vT51c
-----END PRIVATE KEY-----
]]--local pub, err = resty_rsa:new({ public_key = rsa_public_key })
if not pub thenngx.say("new rsa err: ", err)return
end
local encrypted, err = pub:encrypt("hello")
if not encrypted thenngx.say("failed to encrypt: ", err)return
end
ngx.say("encrypted length: ", #encrypted)local priv, err = resty_rsa:new({ private_key = rsa_priv_key })
if not priv thenngx.say("new rsa err: ", err)return
end
local decrypted = priv:decrypt(encrypted)
ngx.say(decrypted == "hello")-- 上面的代码都是测试lua本身的rsa加解密、下面的代码是java生成的密钥对来加解密-- java生成的公钥
local service_pub_key = [[-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjOelR+t9wAL2f0s3xZA
cm2un1cegpQsdSmXvdD0MmfLkrsVAXZl2Qc3V4P0dbtoehqoQk+1L58blDfscT5
yWwp+g7TP+bQwNyCVf2lgOu3kK/ZWQb746y3gbt4bgAtBJXaI19BUAZ1drT0x4i
aTA5FoS4A3hlVVGU0H1ocVb5wLgMc3osIv6XxrOcMwiNJMxfKvMRo6PN+4b+XHA
JnUjXp1mpfnOF3Ck5IlmchMQAJ5ncRC9DUEkr4NXB2uDT36kSU6nxRR8v9U5QO4
xNRjYGtgFHPww6w30ZeHNKiOp2/cTpIdSjahJCfEuXJ3htOHbO8/iMyK3lsPHZw
rIIYdrwQIDAQAB
-----END PUBLIC KEY-----]]
local server_pub, server_err = resty_rsa:new({ public_key = service_pub_key,
key_type = resty_rsa.KEY_TYPE.PKIX,padding = resty_rsa.PADDING.RSA_PKCS1_OAEP_PADDING})
if not server_pub thenngx.say("new rsa err: ", server_err)return
end
-- 使用java生成的公钥加密
local ser_encrypted, err = server_pub:encrypt("6zUwU5McVrZdkKMs@vpgmUFeRd9Ms5o7G")
ngx.say(ngx.encode_base64(ser_encrypted))
-- java代码使用公钥加密的结果
local pub_pass_str = "Z7W7qJhA+rj/qxDkT3Yr3u6GkoAg88q9Ct5IurQUdwqEJGrBx172Pez8js1mnpekiFljdkhb96+JyKi8odhIXkNGEFMcSYoLBFxyQK3wzcpdzm1RXEvmSHmGLsgMTebWlIFiZnfC7PnKaxS3EF/omHmYt9IQBEqN6XAHVE6IB9K4TPGvoraPGbzJqdMr4D6CYZ2KsKKgdyjBOUJMN9UrKCvcuruXwknOXV4i8R46XwM9g8YcAH8Hfmujo07YDVicxy5dWTS3/M56zzSbeTIv67lENeiSSygtKAcrIZF+dRM6NAULckoyPAsD7SWX68AGql4dxS1fQw7EpWZTRvkaMA=="
-- java代码生成的私钥
local service_priv_key = [[-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCM56VH633AAvZ
/SzfFkByba6fVx6ClCx1KZe90PQyZ8uSuxUBdmXZBzdXg/R1u2h6GqhCT7Uvnxu
UN+xxPnJbCn6DtM/5tDA3IJV/aWA67eQr9lZBvvjrLeBu3huAC0EldojX0FQBnV
2tPTHiJpMDkWhLgDeGVVUZTQfWhxVvnAuAxzeiwi/pfGs5wzCI0kzF8q8xGjo83
7hv5ccAmdSNenWal+c4XcKTkiWZyExAAnmdxEL0NQSSvg1cHa4NPfqRJTqfFFHy
/1TlA7jE1GNga2AUc/DDrDfRl4c0qI6nb9xOkh1KNqEkJ8S5cneG04ds7z+IzIr
eWw8dnCsghh2vBAgMBAAECggEASH1T9rAcPZBIqCxWQPlm/j5gVgchikcxhnjyu
+Y8eWcQZylrd7vfrvLqOZl+bu0gDz+mz7Og/VjBtnOdmQeCOBZPgDjjh85PuMwh
h/8NdT1MfjFX4WUIcm0UNVLaJBhr5hPxleTIFGJQ/rbkvEtaQSBl3YbGq0D3sRW
Z/OO/6BQ7PhVWMsqexAbgKQU3MhCoZoURovffdbxhNJQiOR2oQnf31+4MV6f8QV
2UTCvhsb2Z8ybXMCJGUssRkSud2rkOB+T1/vqDOADEdo6Srozlq4iQ7FgbyApsF
9G1ZEjF8L0AC+9eCZSivYvTJceqO9/KHSJtBhnm7hFz2EMVi7ZPwQKBgQC/ScXb
lSuMASwGuWnU2kWIrsy3h7R/PqfeN4AjeIWZGOIkjrQQ0l+y1HjRW3aJ5yWqtsP
Yf2y+t/+7h3tLZ8AS4UrJTgRV3p/cBOD6GGfjOfdAxCpcaofwwl8ZA4CXMUxbbJ
UogQHnmAwfBPlkH2YUcfpS+ZuuZVsHYgBD8rsNPQKBgQC8koBZlLv9JyFgmz/rk
ABBJy6u4Th/spn7qYuiWXGMo/EPAdDeTQVf750/8bV5kv4hZysCz8j9isYtvGYR
CuRvcaaGBjMIJ7sV7YTHH9phoon+Gzf/kUWQslFupWu/9Dv60Nb3iOD26oKfBFf
NhlfczPVXhQnttQkgZ8GM+CGI1QKBgBkcOw/fHg9L3Bap4j2hxXzyzUbOVqBZfj
nKeVSuroLxZEY+QV7v7sYP5Cg/ZGkn4abuRPk3iPPkPXrFhybX4LvZvTJ9vk3zY
nLEZTAPYhvO8SkcVx84kM3HBirHberq+sYJk+70OGbJa9Xqlj5RbNoEOEMKJyiW
f4ORls1UoL9VAoGAHIF8+427WUp4BjWR1RdAopi8utz7AHrMQjngDNu+iYci4qT
goSo9fMIpIEh2qXkqB3ykCNnGRWWcDb/kIgFmhN5GUQ5Q2pO++VKddsh+57F9cL
dGoNCiFnyOSM6i2jKeeozlYigD8e+DbWxnpX8AezVUhTVsSc3LImXs4VWFJD0Cg
YBQPpWmlcij6zD1Qdgb6X6YcZBI/vfwQO8LoDerr6AwJImwHswHz7gENCeT99ZN
IORX+wKRutMHSLiIFIw3XGpkg1cp3m4hHvdDsLIGIWZaIQBDEMOOdRsDGKDBl9R
GpwEUgsRssMuVjOHRijicIA86yu3wzP6sO+7ttHCnBO8Aig==
-----END PRIVATE KEY-----]]
ngx.say(service_priv_key)
local service_priv, service_err = resty_rsa:new({ private_key = service_priv_key ,key_type = resty_rsa.KEY_TYPE.PKCS8,padding = resty_rsa.PADDING.RSA_PKCS1_OAEP_PADDING
})
if not service_priv thenngx.say("new rsa err: ", service_err)return
end
-- 使用java生成的私钥、解密java使用公钥加密的密文
local service_priv_de = service_priv:decrypt(ngx.decode_base64(pub_pass_str))
ngx.say(service_priv_de)

nginx配置

server {
        listen 6377;
        location /rsa {
            default_type text/html;
            content_by_lua_file lua/rsaUtil.lua;
        }
    }

测试

我们直接调用http请求测试

postman请求:http://localhost:6377/rsa

返回结果如下:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2NR1y6fpnJYbQGyuwOt3
2zNaUUTgOvcD2TwzyAFffNYatTal/ol5uFbMd62B+AKtZRY3tdMbJ/WWtQLN6pq4
/v1W6v2Be0bsqfGYD7Xjyg7VChKUJb6f31dEygPCxCkTBic5AWYwDLBfIM4k5hTm
oXJwZw5yUEEk4/xCnUNVp9ZpOY5I32XXbleeO8dBj+WH/pLbt3TBIV/Io6bn+3XX
nfPAyrJl5wTheUPFB/Dhcn2hF8q6Vtr8TjRK945Pgeh9JgVdGgLBcpImxAKBdAaD
BvtTu9NxgwB1Eus0m2OPbcAMFgNns0ikDViGkc+nEv+WYBc7kEMNqVw0eN7qxhNN
BwIDAQAB
-----END PUBLIC KEY----------BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDY1HXLp+mclhtA
bK7A63fbM1pRROA69wPZPDPIAV981hq1NqX+iXm4Vsx3rYH4Aq1lFje10xsn9Za1
As3qmrj+/Vbq/YF7Ruyp8ZgPtePKDtUKEpQlvp/fV0TKA8LEKRMGJzkBZjAMsF8g
ziTmFOahcnBnDnJQQSTj/EKdQ1Wn1mk5jkjfZdduV547x0GP5Yf+ktu3dMEhX8ij
puf7dded88DKsmXnBOF5Q8UH8OFyfaEXyrpW2vxONEr3jk+B6H0mBV0aAsFykibE
AoF0BoMG+1O703GDAHUS6zSbY49twAwWA2ezSKQNWIaRz6cS/5ZgFzuQQw2pXDR4
3urGE00HAgMBAAECggEAGEO+YuoJhJJvvkfrTn+LTCZ1Bv80MKUP8zF/gfRVYTz8
hCb3cIKl8nEUNJhgIQb7rIJN/bUAJvqewObtcEGcTjy/i1CPOuJ2/ZWhtLBgK255
fMUTex3X+kBj3E+LbjRCgr/E61kqK2FZY+xtyKmyHYMW/RFqzXxcyn6iXcL5ROzO
2mM5dW6f9Xhf9jV2PGvyXc+QFdWlbYcdz9PKXx0x4uKj95c1Nb0em8+lljGGuU8w
dF83C/6L4G1TUZ2ipevIiK+8fYuIYjoaYewsJJKHE1tkApo3ZQ868qBmbctvBMdc
J5bW7CciQLfAh/2S/4Ia2sYQDIyx6s3Kq+JZlRI4wQKBgQDz4ett51qZCXsxyTBT
Y4KDW7ly+qlVoCN/VA/omhhtzHpnqJXqpLp96q3IM3lzcVulA9g2bPv1HT1TlJUO
zFATcpvFsTb72pYdR2W9tjK0SciO+QoPLIXBR0IxW2lti6LK3rjT9XSt0xQoNMyv
Zc9Z/0/bO/5BGDx+m3KVPy9AtwKBgQDjmnGA9WNeFdKHuUJfaYkbnNkQTpIzMgzE
fu+m0803jQo/bzZajdDDuaaftN9q1W7+0N6jor9EqVkhc0a8FRU4d5MEwoDdwcjp
3HHT+07l6609mvxqq7KfEQGRK6qoeRqjnhbmA9jngKMhJbeJRCclzFOrWwO32ask
mQqvmrlmMQKBgDnxvHERXdosgYOzrHKzmufA3E/wNFluweBXxavbKOC1i4Ojb3Mf
jluqbX26lSmTjlWnkzBjNn3nY5G/JKcubfwg59fRoiG2rqHoO8kWR/fD7A3kJ7qx
NlpUpup5MJRhb91Ji5p4oC9Ijmp7GQK3asuUOJH7MA6hRoZCQrgpGf4DAoGAfBVK
BgVB7Bw3j7jnP38YuY4UJLjBKdoCbenKG4hi3AMvcA/gcRPZmasP9Qe1udesUI1s
o4dpgTRWHE9tY8KWtBc0dqbXfI5WS3DcObZLeDu5Udm5/SmoEuJBmXRV8M09QbBB
SZsVWHif9sVKPzKBqTCw+L2A1G19yVEKK1xN8TECgYAIUFcJ6QS+369rMIgZeaqJ
/9eL929EHAPEbEogkOC4g6ErTUctSH00rrXuj6FFy78ppytpRahxIUtCI4x8j4Hn
Q15HKd2E/qq95P/Hgs6we42gqTak4mme5ZBMiRFrwQ9Pg7nwebj9TUqB3Ev6hFDJ
TDttsBZTyayGfbx3ebdH3w==
-----END PRIVATE KEY-----encrypted length: 256
true
YaHH3mNTdSBM7SHVgx4ZaQe3ebNcpGRxf95GYcHjn7TSZB9YyAiYraT5wF/IIJGW19nzFGg6w4weSSYZxzXSzYQTz0LudXiQOq32a9wm8v1iUrjd5O49QpT0bEguq/zRCEr1gbArvnasQAQWcp3z1XbiF2+7vUH7FfeRgk2yWd3c8YwMRDuR+5kfgSsL24/1eOHOi3I2Uzjgo9TApzNmJ5MUaGevY2vrvRj3YqXbzgkaGxC9CgrV2fvSpcs24cTvToDgckEaxqWlodmBmvhlR5XlbX5xISB/R84K7jkYtNZFo92Es1mTpxqgAwYnA8nL231hkbFLwxUx1GcOvF+ucQ==
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCM56VH633AAvZ
/SzfFkByba6fVx6ClCx1KZe90PQyZ8uSuxUBdmXZBzdXg/R1u2h6GqhCT7Uvnxu
UN+xxPnJbCn6DtM/5tDA3IJV/aWA67eQr9lZBvvjrLeBu3huAC0EldojX0FQBnV
2tPTHiJpMDkWhLgDeGVVUZTQfWhxVvnAuAxzeiwi/pfGs5wzCI0kzF8q8xGjo83
7hv5ccAmdSNenWal+c4XcKTkiWZyExAAnmdxEL0NQSSvg1cHa4NPfqRJTqfFFHy
/1TlA7jE1GNga2AUc/DDrDfRl4c0qI6nb9xOkh1KNqEkJ8S5cneG04ds7z+IzIr
eWw8dnCsghh2vBAgMBAAECggEASH1T9rAcPZBIqCxWQPlm/j5gVgchikcxhnjyu
+Y8eWcQZylrd7vfrvLqOZl+bu0gDz+mz7Og/VjBtnOdmQeCOBZPgDjjh85PuMwh
h/8NdT1MfjFX4WUIcm0UNVLaJBhr5hPxleTIFGJQ/rbkvEtaQSBl3YbGq0D3sRW
Z/OO/6BQ7PhVWMsqexAbgKQU3MhCoZoURovffdbxhNJQiOR2oQnf31+4MV6f8QV
2UTCvhsb2Z8ybXMCJGUssRkSud2rkOB+T1/vqDOADEdo6Srozlq4iQ7FgbyApsF
9G1ZEjF8L0AC+9eCZSivYvTJceqO9/KHSJtBhnm7hFz2EMVi7ZPwQKBgQC/ScXb
lSuMASwGuWnU2kWIrsy3h7R/PqfeN4AjeIWZGOIkjrQQ0l+y1HjRW3aJ5yWqtsP
Yf2y+t/+7h3tLZ8AS4UrJTgRV3p/cBOD6GGfjOfdAxCpcaofwwl8ZA4CXMUxbbJ
UogQHnmAwfBPlkH2YUcfpS+ZuuZVsHYgBD8rsNPQKBgQC8koBZlLv9JyFgmz/rk
ABBJy6u4Th/spn7qYuiWXGMo/EPAdDeTQVf750/8bV5kv4hZysCz8j9isYtvGYR
CuRvcaaGBjMIJ7sV7YTHH9phoon+Gzf/kUWQslFupWu/9Dv60Nb3iOD26oKfBFf
NhlfczPVXhQnttQkgZ8GM+CGI1QKBgBkcOw/fHg9L3Bap4j2hxXzyzUbOVqBZfj
nKeVSuroLxZEY+QV7v7sYP5Cg/ZGkn4abuRPk3iPPkPXrFhybX4LvZvTJ9vk3zY
nLEZTAPYhvO8SkcVx84kM3HBirHberq+sYJk+70OGbJa9Xqlj5RbNoEOEMKJyiW
f4ORls1UoL9VAoGAHIF8+427WUp4BjWR1RdAopi8utz7AHrMQjngDNu+iYci4qT
goSo9fMIpIEh2qXkqB3ykCNnGRWWcDb/kIgFmhN5GUQ5Q2pO++VKddsh+57F9cL
dGoNCiFnyOSM6i2jKeeozlYigD8e+DbWxnpX8AezVUhTVsSc3LImXs4VWFJD0Cg
YBQPpWmlcij6zD1Qdgb6X6YcZBI/vfwQO8LoDerr6AwJImwHswHz7gENCeT99ZN
IORX+wKRutMHSLiIFIw3XGpkg1cp3m4hHvdDsLIGIWZaIQBDEMOOdRsDGKDBl9R
GpwEUgsRssMuVjOHRijicIA86yu3wzP6sO+7ttHCnBO8Aig==
-----END PRIVATE KEY-----
6zUwU5McVrZdkKMs@vpgmUFeRd9Ms5o7G

openresty 与 java RSA加解密相关推荐

  1. java:RSA加解密字符串与byte[]数组转换 不用String方法的原因

    RSA加密参考https://blog.csdn.net/qq_18870023/article/details/52596808 byte负数转换参考https://bbs.csdn.net/top ...

  2. rsa java ao_RSA加解密工具类

    Java 实现 import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairG ...

  3. RSA加解密用途简介及java示例

    在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...

  4. Java中的RSA加解密工具类:RSAUtils

    本人手写已测试,大家可以参考使用 package com.mirana.frame.utils.encrypt;import com.mirana.frame.utils.log.LogUtils; ...

  5. 与非java语言使用RSA加解密遇到的问题:algid parse error, not a sequence

    遇到的问题 在一个与Ruby语言对接的项目中,决定使用RSA算法来作为数据传输的加密与签名算法.但是,在使用Ruby生成后给我的私钥时,却发生了异常:IOException: algid parse ...

  6. 前后端java+vue 实现rsa 加解密与摘要签名算法

    RSA有两个密钥,一个是公开的,称为公开密钥:一个是私密的,称为私密密钥. 特点: 公开密钥是对大众公开的,私密密钥是服务器私有的,两者不能互推得出. 用公开密钥对数据进行加密,私密密钥可解密:私密密 ...

  7. RSA加解密,.net公钥/私钥兼容java

    背景介绍 之前老程序使用.net进行数据的RSA加解密,现在用JAVA重写,但是.net的公钥和私钥是xml格式,跟java的不一样,需要手动转换一下.目前网上的大部分都是java转.net.我这里来 ...

  8. java RSA加密解密实现(含分段加密)

    该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar 下载地址:http://download.csdn.net/detail/centralperk/50255 ...

  9. RSA加解密的OAEP MGF1 填充解析

    RSA加解密的OAEP MGF1 填充解析 加密时的填充 PKCS#1 v2.1: RSA密码学规范中关于 OAEP的模式的讲解如下: RSAES-OAEP-ENCRYPT (( n, e), M, ...

最新文章

  1. 手把手教你用Keras进行多标签分类(附代码)_数据派THU-CSDN博客 (翻译:程思衍校对:付宇帅)
  2. 解决nodejs环境下端口号被占用的方法
  3. 数据传输完整性_生产系统数据完整性事件常见指标(下)
  4. git 为什么会有多个head_继续学习Git
  5. C# 检查当前系统已安装的程序app/两种方法检测
  6. python简易停车系统
  7. 原来使用 Spring 实现策略模式可以这么简单!
  8. 2022iOS面试题集锦(iOS interview)
  9. antd form validateFields的校验指定元素
  10. 科学计数法(PAT)
  11. 2020香港公司开户的一些个人见解?香港银行开户免踩坑。
  12. 囧人又做了哪些囧事呢?
  13. 软件开发人员 梦想最大的阻碍:毒、赌、黄
  14. 理论小知识:集合之srem
  15. 行为管理(锐捷睿易篇)
  16. uniapp使用插件 小程序正常 app报错cid unmatched at view.umd.min.js:1
  17. GSM/GPRS之二-短信pdu详细解析
  18. 淘宝的直播视频怎么下载啊?有好的方法没有,越简单越好
  19. vue中的@keyup事件
  20. PyQt5 QtChart-曲线图

热门文章

  1. 【脚本】网页端微信读书书架中书籍详细信息
  2. Android底部菜单栏(图片+文字)
  3. 需要一个自习室系统,包括收费、灯控、会员管理、微信及前端订座、一卡通终端,会做的私信我,有偿。
  4. onenote标注pdf笔记_如何高效利用OneNote做笔记?
  5. HDU2066---------Dijkstra算法代码
  6. 建立网站费用大概需要多少钱?如何计算建立网站的成本?
  7. 学车笔记(科目二——总结)
  8. Thread.Sleep vs. Task.Delay
  9. UI设计初学者必入门必看!
  10. iOS 系统方法获取当前位置经纬度