企业微信会话存档开发与问题
不得不说企业微信会话存档那块给的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这个文件放在根目录下