企业微信的绘画内容存档 RSA解密实例

起因,公司要对企业微信的内容进行监控,真TM 变了态了,完后领导让我调研写个demo,我要通过不断的努力让这个功能不好用 ヾ(◍°∇°◍)ノ゙
 
 
1,首先在企业微信里面 添加这个 "绘画内容存档",需要超管来创建
这里面两个"开启范围" 就是苦逼的我,"可信ip"就是公司的ip, 最主要就是下面的公钥私钥 和Secret 要保存好下面要用
 
 
2, API文档的位置在
 
 
 
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
 
 
 
4, 下载一个官方的demo
 
 
 
 
5, 上代码 我只列出 核心部分 和有坑部分
 
初始化没啥可说的, 那些参数 在官方文档上有解释对一下就行,把 之前那些敏感信息都填上  corpid 超管肯定知道不难找
 
GetChatData 是获取会话列表 没啥难度 
 
 
 
关键点是返回值里 的字段 ,一定要好好参照文档,要先base64进行decode在用RSA 解密
这里我懒得导包解析 就直接把那么长的 encrypt_random_key 和 encrypt_chat_msg 给复制下来了,注意本实例没有用 publickey_ver的值来处理解密过程
 
 
 
获取密匙 和 解密过程 直接贴上了 , 原谅我的不会排版.
最关键的是这个方法
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);
        }
    }
}
 
 
返回的格式 可以参照文档每个字段的意义
 
 
qq:48564021  欢迎交流
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值