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

摘要:
企业获得消息内容后,首先需要base64解码,使用消息的私钥来指示版本,并使用RSAPKCS1算法进行解密,以获得解密的内容,为下一步的消息明文解析做准备。对接收到的消息进行加密_random_key是base64decode,然后使用相应的私钥使用rsa算法进行解密。请注意,需要RSAPKCS1。对于Java,主要使用PKCS8,因此在实现算法时应注意正确选择文档中描述的算法。

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

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

在线rsa加解密工具http://tool.chacuo.net/cryptrsaprikey

在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

免责声明:文章转载自《企业微信会话存档消息解密(Java RSA PKCS1解密)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Delphi指针及其它(转)java 实现redis缓存下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【环境巡检】使用jmeter+ant+Jenkins+企业微信自动化巡检_jmeter实现脚本及响应超时、失败重试(1)

 一、分析准备  由于项目上线了,需要尽快接入巡检避免环境挂了不自知。虽然运维有运维侧的监控,但是测试还是从业务侧的巡检是否成功开展一些工作比较好。经过了一番调研决定使用jmeter+ant+Jenkins+企业微信自动化巡检及相关通知。 经过分析,我们要做如下的准备: 1、jmeter:实现巡检的接口调用,判断前后端接口返回内容、响应时间是否正常; 2、...

RSA加密前端JS加密,后端asp.net解密,报异常

RSA加密前端JS加密,后端asp.net解密,报异常 参考引用:http://www.ohdave.com/rsa/的JS加密库 前端JS加密代码: function GetChangeStr() { debugger; var pwdStr = document.getElementById("txtPa...

C#实现Base64编码与解码

一、编码规则      Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节数组。以3个字节为一组。按顺序排列24 位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所要编码的数据的字节数不是3的整倍数,也就是说...

VMWare Esxi 6.5(实际为5.x,6.x)时区问题

Esxi不支持修改时区,但是可以使用ESX或者Centos 6/7的localtime文件进行替换以实现时区修改,问题是,重启后文件会被还原。 详细的纠结过程就不说了,终级解决方案如下(给公司写的,现分享出来): 大概思路是:将centos 6中/usr/share/zoneinfo/Asia/Shanghai文件(如果是它国时区,请自行替换base64内...

你不知道的 Blob

来自公众号:全栈修仙之路 如果你允许用户从你的网站上下载某些文件,那你可能会遇到 Blob 类型。为了实现上述的功能,你可以很容易从网上找到相关的示例,并根据实际需求进行适当的调整。对于部分开发者来说,在完成上述功能之后,他们并不会继续思考 Blob 是什么? 这就导致了一些开发者,还是停留在熟练使用 API 的层面,当遇到比较棘手的问题时,就束手无策...

支持复制粘贴word公式的CKEditor编辑器

由于工作需要必须将word文档内容粘贴到编辑器中使用 今年年底flash将不再被浏览器支持 但发现word中的图片粘贴后变成了file:///xxxx.jpg这种内容,如果上传到服务器后其他人也访问不了,网上找了很多编辑器发现没有一个能直接解决这个问题 考虑到自己除了工作其他时间基本上不使用windows,因此打算使用nodejs来解决这一问题 发现不管什...