不得不說企業微信會話存檔那塊給的sdk過於敷衍啊;比如加密算法啥的都沒有;今天正好有這個需求整理下:
首選下載官方給的sdkJava版本 ;然后你會看到在解密那塊注釋只是會提醒你一下,不得不說太敷衍了;將代碼添加解密過程
else if (args[0].equals("3")) { String encrypt_key = null; try { encrypt_key = RSAUtils.getPrivateKey(args[1]); } catch (Exception e) { e.printStackTrace(); } long msg = Finance.NewSlice(); ret = Finance.DecryptData(sdk,encrypt_key ,args[2], msg); if (ret != 0) { System.out.println("getchatdata ret " + ret); return; } System.out.println("decrypt ret:" + ret + " msg:" + Finance.GetContentFromSlice(msg)); Finance.FreeSlice(msg); }
下面我整理了下整個流程
根據微信的api文檔 問答模塊;
在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
如果不轉成pkcs8 則會報錯java.security.InvalidKeyException: IOException : algid parse error, not a sequence;
這時會產生3個文檔;將公鑰整個都復制到要填的文本框中;將私鑰復制到你的解密代碼中
package com;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
/**
* Java RSA 加密工具類 參考: https://blog.csdn.net/qy20115549/article/details/83105736
*/
public class RSAUtils {
private static final String privKeyPEM = "-----BEGIN PRIVATE KEY-----\n" +
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCSorzatM71c/j1\n" +
"79JQwZYqeaJfQaQWXIoBD0R2ZCyo9iTWtHAIvxfUJKahu/khgFPJ2jSJ+LfeieDv\n" +
"1MZv6qkISc3Hg6JCuMynzcEdfSGXeawOkYr2lRrOScedmo1FyB8m086HdjT6BuDZ\n" +
"1K2H+iMZjItOggmWcZ5Bd9RLTaAOHE0WyuO1/gE3eqtgOddmvBS+OS2kB/DPTQJ1\n" +
"CLYsnXjlGfHWrNqJEehtgRNf6spem26rE4CfWURxECram+m0wgTjCC4Ta8vARba+\n" +
"HMdZ1ROHfqdxGL5RFC498eWkLM5HQeSeetGAWrA+RGWEO7xk8aPQGej9PsSwc1H/\n" +
"x5h+5ntnAgMBAAECggEAQ6mmXYErMqXmDo4wTSVXBpiD7VKbxdnDsIN8Aulsljam\n" +
"fxBZ1h9ffnu/DEhxyBywDSeMMNI8/go/akuTmZb9kp6DvvmlyQX/IbtWziWsd3ok\n" +
"g8BzEB9zdBclbjsfz0Bt53u7BFTuUyUTYlC6FlG9Go/4xCxLAknBTdJeerUCEyAX\n" +
"Pdk2CaUEzZJxgpgome/AjaVkIym30fMoZKodccdc0TZoBaIW+Bkaj4mvPc7x6ShK\n" +
"rRohvpNghIttblkQqjqIdaraK7kpQNTec2MKLpLdFX3d8tiJGo+ROr7dpWKQoc6p\n" +
"k1PwHJpCGa9en26EyY1uwHtm/+GA8rAttvyogW0M6QKBgQDDc36Bh1kJGeUQw0WI\n" +
"a3YZLVkn7+foDzb7agJJyQUDIuWDdiRMhcqz5CW35p/BGeshCTxh6u1HYCA5hZpb\n" +
"zD3vCrpwjF+D2MJSpMhnV/1hHtw3xTNd6jAw8AgIrrkb0iahuXf6Ad4jvzU3a/hj\n" +
"jV7atzRvniOH+OiGX4rjeob7BQKBgQDAD97vrm/Amnim3t5BMv06PWYhwMYH7G14\n" +
"sQ0gg+R06D8Am1l9qieQkPCRrnzXEWvCyfwJ3Zid8SItGWOXWDkGoYwbFNs5eJUh\n" +
"x4ZkT5RMgjEXF7tSPRVGwV8P8X8xX/3QzrNbacb2KTmwuZXsqb1/vvNyP/D2eFSa\n" +
"/cAeYmJgewKBgF6sVg3mAsG+0k8xV0ACVZ1Scwo+UgX9QLO9oMge4Bep0qTAGEsc\n" +
"z5gdngubYazGojdJYv9HLZJSRKm4RpHKuAFPIAoeZLHX0CD6ArzUST6/FQrKsdv+\n" +
"8ULzMeEKyU1pmR7jWPM37mNAXkWvPgzy0Ix/C545apqVfgSAySTxF+sFAoGBAKuB\n" +
"wKex0nNgvZrt6/S27rBCQeCkP3K16u/a0wkVHj5TYmdNUnXIK3qKI3lEIpD/KoaQ\n" +
"TjQVIQLxYH57bJaqnonQWseYMUe56Rp4DQeolJpZrDKd65W9nDFJ3nTjR5y0xnff\n" +
"DQT1iUkqeSzaHQpwbRsVTlnYxXmi7JJXRGcdnhHfAoGAG+QMQpuuKQ2vWbU/D8tf\n" +
"uRBwul8E1+Fa85uXQ9GpXg+exnvkr9ffycetjgclJa9vwlaeiOWU3BYrstYb0sW5\n" +
"anh4mRzWwBBEG0Zi1k8esIAKYIa5sbl0DSXKhX35d7C92deMJXrNkCYigeaUWhBg\n" +
"pvZ4EZ5pTd3In+34rdM6GvU=\n" +
"-----END PRIVATE KEY-----";
// 用此方法先獲取秘鑰
public static String getPrivateKey(String str) throws Exception {
String privKeyPEMnew = privKeyPEM.replaceAll("\\n", "").replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "");
byte[] decoded = Base64.getDecoder().decode(privKeyPEMnew);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decoded));
// 64位解碼加密后的字符串
byte[] inputByte = Base64.getDecoder().decode(str);
// RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
}
注意一定是要轉成pkcs8文檔里面的私鑰;此時一定要注意微信會話文檔返回的 publickey_ver 號,如果你改變了它,之前的消息還是原版本號;新消息才是最新的版本號;不然會報:BadPaddingException: Decryption error
還要注意的一點是Finance.java這個類的包名不能改變;不然就找不到那個libWeWorkFinanceSdk_Java.so文件 ;libWeWorkFinanceSdk_Java.so這個文件放在根目錄下
