起因,公司要对企业微信的内容进行监控,真TM 变了态了,完后领导让我调研写个demo,我要通过不断的努力让这个功能不好用 ヾ(◍°∇°◍)ノ゙
1,首先在企业微信里面 添加这个 "绘画内容存档",需要超管来创建
这里面两个"开启范围" 就是苦逼的我,"可信ip"就是公司的ip, 最主要就是下面的公钥私钥 和Secret 要保存好下面要用
![](https://i-blog.csdnimg.cn/blog_migrate/3e4a7b79697bbcf833e5418e40b4a1c0.png)
2, API文档的位置在
![](https://i-blog.csdnimg.cn/blog_migrate/c18496d60ee33c817b2d3ccf11b4c84a.png)
3,提前准备下私钥
私钥大概是这个格式
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDMpbS+zJx30tcP3PTN/M/VK5A9jEhSdjuS5wEnxE+FAWk+W0TZ
TJAzq1aR+LorCFwQGLlxsUH1XUwI/Dy3WclES9ZDiaT3ukg9k+A1JH4mEEpiAqcI
V001jZnh9GlL7D07NuPCrolO50mpCfB6yRYQdzKthMOALjTGgwhZXn8rUQIDAQAB
AoGAXw5FEy7lKr8TR/oA98ELJF/0wrHrUeo7J7QHFFqZ+RS7tswcAbcPcACQ2IKo
rp5WbN+fG5ETKw4n6DCJXzzkP/ADuabysbB68S0GBgGk6U+yG4auW5ZUYyP5BBaa
xcUT/gJG+3xiR+WLMcn6rx/dSs7j22WWc/YLG1ud6Ri3pNUCQQD+vNDXqCRjyGr7
QuYWtAlC0xXdo7tFdJkaDk86EGqtpHkb8yXRvNtB+/wWAWypo9gUSsrOJqJ9Rz70
BrbSIY5LAkEAzalXSm+YjXOSlOvDQxUgpAcgeYgN8vUduO6yqawBtzX10HSFY042
EkAdyNR/FftTlxlql/xg/N3xZaufcsB7UwJBALcNC63Mv8mMXYQMwLaTzQveD5pj
a9EvRk149umsnlwFEppJEWY0JgK2hqFxiJomiMGcNTwKez03Ez/cC0fYoR0CQQCS
ODrStmMM9sWZ0cHDOQs688I4Be589Z8LM9K5alWnCvH6IBJqXqyIRnMBqDQfR7i
R/TMWGiQgC+37Hxx9r33AkBlvrR9cuHXJmWlmmzVzUKut9LCcziBvPqQA3Gcy+kd
8vSyTDVspEwzKPFUO3zpEUOvoldC/GCC3JtMbdHkfvC6
-----END RSA PRIVATE KEY-----
但是不能直接用需要通过OpenSSL转换成PKCS1, 我是在linux机器上导出来的
openssl pkcs8 -topk8 -inform PEM -in 原始key -outform PEM -out 生成key -nocrypt
我生成的时候 命令如下
openssl pkcs8 -topk8 -inform PEM -in id_rsa -outform PEM -out rsa_private_key_01.pem -nocrypt
然后最重要的是要把上下 -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- 给去掉
在工程中 不管你是定义成变量还是读取本地文件都要去掉 否则报错
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : Short read of DER length
![](https://i-blog.csdnimg.cn/blog_migrate/6abafdde0f8a0d83f64ce104fe7c33cb.png)
4, 下载一个官方的demo
![](https://i-blog.csdnimg.cn/blog_migrate/947c17a554991b172f449bad33bbee1d.png)
5, 上代码 我只列出 核心部分 和有坑部分
初始化没啥可说的, 那些参数 在官方文档上有解释对一下就行,把 之前那些敏感信息都填上 corpid 超管肯定知道不难找
GetChatData 是获取会话列表 没啥难度
![](https://i-blog.csdnimg.cn/blog_migrate/7a8ab54af69c76c95556f7ab001e2e9a.png)
关键点是返回值里 的字段 ,一定要好好参照文档,要先base64进行decode在用RSA 解密
![](https://i-blog.csdnimg.cn/blog_migrate/769dc53d88afed556c078af713e9a774.png)
这里我懒得导包解析 就直接把那么长的 encrypt_random_key 和 encrypt_chat_msg 给复制下来了,注意本实例没有用 publickey_ver的值来处理解密过程
![](https://i-blog.csdnimg.cn/blog_migrate/24feaa56c772e32c8f17df1b790e1037.png)
获取密匙 和 解密过程 直接贴上了 , 原谅我的不会排版.
最关键的是这个方法
byte
[]
decrypt
=
decrypt
(
dataBytes
, privateKey,
2048
,
11
,
"RSA/ECB/PKCS1Padding"
)
2048 就是上面那个
使用模值为2048bit的秘钥,默认是128 特别坑,不改会报错
Caused by: javax.crypto.BadPaddingException: Decryption error
//获取私钥
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = (new BASE64Decoder()).decodeBuffer(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
//解析数据
public static String decrypt(String data, PrivateKey privateKey) throws Exception {
//先decode 从base64 转出来
byte[] dataBytes = decoder64.decode(data.getBytes(CHARSET));
//在去使用RSA PKCS1算法进行解密
byte[] decrypt = decrypt(dataBytes, privateKey, 2048, 11, "RSA/ECB/PKCS1Padding");
String s1 = new String(decrypt);
return s1;
}
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);
}
}
}
返回的格式 可以参照文档每个字段的意义
![](https://i-blog.csdnimg.cn/blog_migrate/128de7ac51da85a53fef386b31b5ef28.png)
qq:48564021 欢迎交流