pkcs1解密 springboot_企业微信会话存档消息解密(Java RSA PKCS1解密)

https://www.cnblogs.com/eleclsc/p/12082000.html

转:https://www.cnblogs.com/zengsf/p/10136886.html

在linux环境中生成公私钥:

openssl

然后生成私钥:

genrsa -out app_private_key.pem 2048 # 私钥的生成

在利用私钥生成公钥:

rsa -in app_private_key.pem -pubout -out app_public_key.pem #导出公钥

这样就生成了rsa2的私钥和公钥了。可以用于支付宝的公密钥的生成

pkcs1转pkcs8

openssl pkcs8 -topk8 -inform PEM -in app_private_key.pem -outform pem -nocrypt -out pkcs8.pem

1. 只需要使用pkcs1

Q:拉取的消息如何解密?

A:企业微信对待存储的消息使用企业最新上传的公钥进行加密,企业自行使用对应版本的私钥进行解密。对json消息体内的encrypt_random_key,base64处理后首先使用对应版本的私钥进行解密得到字符串内容,将字符串内容与消息体内的encrypt_chat_msg,使用sdk的接口DecryptData,得到真正的明文消息。

这文档写的,稀烂。

如果只看上面的描述,并且你用Java去实现,那么在解密时,你十有八九是搞不定的。其实在接口文档处,还有一处这样的描述:

encrypt_random_key是使用企业在管理端填写的公钥(使用模值为2048bit的秘钥),采用RSA加密算法进行加密处理后base64 encode的内容,加密内容为企业微信产生。RSA使用PKCS1。

企业得到消息内容后,需先进行base64 decode,使用消息指明版本的私钥,使用RSA PKCS1算法进行解密,得到解密内容,为下一步进行消息明文解析做准备。

翻译一下:

需要对接收到的消息中encrypt_random_key进行base64 decode, 然后使用对应的私钥,使用rsa算法进行解密,注意需要使用RSA PKCS1。对于Java来说,大都使用PKCS8,所以需要注意在实现算法时,需要正确选择文档所说的算法。

私钥是PKCS1(一般以如下开头:begin rsa private key)或者是PKCS8(一般以 begin private key 开头)版本的,都ok,只要选择了正确的私钥读取方式就ok。

读取公钥:

public static PublicKey getPublicKey(String base64PublicKey){

PublicKey publicKey = null;

try{

X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey.getBytes()));

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

publicKey = keyFactory.generatePublic(keySpec);

return publicKey;

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (InvalidKeySpecException e) {

e.printStackTrace();

}

return publicKey;

}

读取pkcs1格式的private key

public static PrivateKey getPrivateKey(String privKeyPEM) throws Exception{

String privKeyPEMnew = privKeyPEM.replaceAll("\\n", "").replace("-----BEGIN RSA PRIVATE KEY-----", "").replace("-----END RSA PRIVATE KEY-----", "");

byte[] bytes = java.util.Base64.getDecoder().decode(privKeyPEMnew);

DerInputStream derReader = new DerInputStream(bytes);

DerValue[] seq = derReader.getSequence(0);

BigInteger modulus = seq[1].getBigInteger();

BigInteger publicExp = seq[2].getBigInteger();

BigInteger privateExp = seq[3].getBigInteger();

BigInteger prime1 = seq[4].getBigInteger();

BigInteger prime2 = seq[5].getBigInteger();

BigInteger exp1 = seq[6].getBigInteger();

BigInteger exp2 = seq[7].getBigInteger();

BigInteger crtCoef = seq[8].getBigInteger();

RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

return privateKey;

}

java rsa pkcs1解密实现:

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

cipher.init(Cipher.DECRYPT_MODE, privateKey);

return new String(cipher.doFinal(data));

加密时只需要在cipher.init时传入对应mode为Cipher.ENCRYPT_MODE, publicKey即可。

对于已经base64 encode的字符串解密时,只需要先进行base64.decode,得到byte[]作为要解密的data进行解密即可。

参考资料:

https://www.devglan.com/java8/rsa-encryption-decryption-java

http://defned.com/post/java-rsa-pkcs1/

https://github.com/greigdp/Javacard-ALG_RSA_SHA256_PKCS1

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值