公司需要开启企微聊天记录记录员工聊天记录方便审计工作,我很幸运的来踩坑了。
【一】、SDK语言选择
sdk只提供java和c#版本,其他版本在社区找第三方编译版本
【二】、RSA密钥生成
密钥长度2048,PKCS#1 ,100%不会遇到坑的在线生成地址送给你:
https://www.bejson.com/enc/rsa/
公钥在企微后台配置即可。
【三】、请求IP白名单
企业微信的IP白名单延迟及其久,因此您设置了允许依然提示不允许,你只能等,没有别的办法。
【四】、解密有时候成功有时候失败
切记企业微信的加密是根据证书版本进行加密的,每条消息都能获取到版本,字段为publickey_ver,如果您配置了多次证书在企微后台,那么你需要根据publickey_ver来取不同的证书进行解密。当然你可以判断低于目前的版本消息全部忽略掉。
【五】、Windows下WeWorkFinanceSdk.dll相关动态链接库保存在哪里呢?
全部保存在jdk的bin目录,例如我保存在这个目录下面:
C:\Users\gao\.jdks\corretto-1.8.0_362\bin
【六】、Linux下libWeWorkFinanceSdk.so放在哪里
我启动jar程序时候看到提示找不到,并且报错了环境变量目录/usr/lib64/,于是我把so文件保存在这里,然后执行ldconfig命令更新共享库缓存,成功启动
【七】、Sdk包名称注意
com.tencent.wework.Finance映射的是动态链接库,因此包名称不能修改。为了适配linux和windows您还需要修改sdk的代码:
static { String os = System.getProperty("os.name").toLowerCase(); if (os.contains("win")) { System.loadLibrary("WeWorkFinanceSdk"); } else { System.loadLibrary("WeWorkFinanceSdk_Java"); } }
【八】、请求字段seq字段的坑
切记第一次获取seq值传0,第二次不能直接自增+1,需要根据返回的消息的seq值进行+1,因为有时候你发现seq会跳,mdzz。
【九】、RSA私钥格式问题
-----BEGIN PRIVATE KEY----- 不需要这个格式标识,删除掉,不需要换行符号,删除掉。
【十】、贡献代码1:将字符串的私钥加载变为PrivateKey类型
private PrivateKey getPrivateKey(String key) throws Exception { byte[] keyBytes; keyBytes = (new BASE64Decoder()).decodeBuffer(key); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePrivate(keySpec); }
【十一】、贡献代码2:私钥解密公钥代码
/** * decrypt * * @param data * @param privateKey * @return * @throws Exception */ public static String decrypt(String data, PrivateKey privateKey) throws Exception { byte[] dataBytes = java.util.Base64.getDecoder().decode(data); byte[] decrypt = decrypt(dataBytes, privateKey, 2048, 11, "RSA/ECB/PKCS1Padding"); return new String(decrypt); } public static byte[] decrypt(byte[] encryptedBytes, PrivateKey privateKey, int keyLength, int reserveSize, String cipherAlgorithm) throws Exception { int keyByteSize = keyLength / 8; int decryptBlockSize = keyByteSize - reserveSize; int nBlock = encryptedBytes.length / keyByteSize; ByteArrayOutputStream outbuf = null; try { Cipher cipher = Cipher.getInstance(cipherAlgorithm); cipher.init(Cipher.DECRYPT_MODE, privateKey); outbuf = new ByteArrayOutputStream(nBlock * decryptBlockSize); for (int offset = 0; offset < encryptedBytes.length; offset += keyByteSize) { int inputLen = encryptedBytes.length - offset; if (inputLen > keyByteSize) { inputLen = keyByteSize; } byte[] decryptedBlock = cipher.doFinal(encryptedBytes, offset, inputLen); outbuf.write(decryptedBlock); } outbuf.flush(); return outbuf.toByteArray(); } catch (Exception e) { throw new Exception("DEENCRYPT ERROR:", e); } finally { try { if (outbuf != null) { outbuf.close(); } } catch (Exception e) { outbuf = null; throw new Exception("CLOSE ByteArrayOutputStream ERROR:", e); } } }
【十二】、所有Finance.NewSlice()都要及时关闭,否则很容易内存溢出。
Finance.FreeSlice(msg);
字节(Byte)是计量单位,表示数据量多少,是计算机信息技术用于计量存储容量的一种计量单位,通常情况下一字节等于八位。字符(Character)计算机中使用的字母、数字、字和符号,比如'A'、'B'、'$'、'&'等。一般在英文...
public class test { public static void main(String[] args) { &...
java限制1个方法同一时间只能被一个线程访问public synchronized void setOrderPay(){ }加上synchronized 修饰符即可...
java判断字符是否是一个字母System.out.println(Character.isLetter('a'));java判断字符是否是一个数字System.out.println(Character.isDigit('0'));java判断字符是否是一个空白Sy...
java stringBuffer(1).stringBuffer和stringBuilder区别stringBuffer是线程安全的,stringBuilder速度更快(2).简单的stringBuffer例子StringBuffer sBuffer = new&nb...
System.out.println("当前时间戳(秒): " + System.currentTimeMillis()/1000); System.out.println("当前时间戳(毫秒): " +&nb...