← 返回文章列表

OA系统加解密代码块

公司网络结构调整,我们需要批量迁移OA系统的代码块中的JS文件地址。代码块在数据库中是以密文形式存储的,22年我们曾尝试过手动编辑和前端自动化脚本的办法,但总归是效率低下,治标不治本。现在我们有了逆向工程手段,可以从根本上解决问题。

分析OA系统的反编译代码,得知其使用的加解密库为org.bouncycastle:bcprov-jdk15on:1.52,所有类型的代码块(流程布局、建模布局、建模查询)的加解密过程完全相同。提取加解密过程,封装为工具类:

package com.company.project.util;

import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.encoders.Hex;

/** 代码块工具类 */
public class CodeBlockUtils {
    private static final byte[] BYTES1 = "WEAVER E-DESIGN.".getBytes();
    private static final byte[] BYTES2 = "weaver e-design.".getBytes();

    /**
     * 将明文编码成密文
     * @param source 明文
     * @return 密文
     */
    public static String encode(String source) {
        try {
            if (source.isEmpty()) return "";
            PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()));
            cipher.init(true, new ParametersWithIV(new KeyParameter(BYTES1), BYTES2));
            byte[] outputBytes = new byte[cipher.getOutputSize(source.getBytes("GBK").length)];
            int length1 = cipher.processBytes(source.getBytes("GBK"), 0, source.getBytes("GBK").length, outputBytes, 0);
            int length2 = cipher.doFinal(outputBytes, length1);
            byte[] resultBytes = new byte[length1 + length2];
            System.arraycopy(outputBytes, 0, resultBytes, 0, resultBytes.length);
            return new String(Hex.encode(resultBytes));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将密文解码为明文
     * @param encoded 密文
     * @return 明文
     */
    public static String decode(String encoded) {
        try {
            if (encoded.isEmpty()) return "";
            PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()));
            cipher.init(true, new ParametersWithIV(new KeyParameter(BYTES1), BYTES2));
            byte[] sourceBytes = Hex.decode(encoded);
            cipher.init(false, new ParametersWithIV(new KeyParameter(BYTES1), BYTES2));
            byte[] outputBytes = new byte[cipher.getOutputSize(sourceBytes.length)];
            int length1 = cipher.processBytes(sourceBytes, 0, sourceBytes.length, outputBytes, 0);
            int length2 = cipher.doFinal(outputBytes, length1);
            byte[] resultBytes = new byte[length1 + length2];
            System.arraycopy(outputBytes, 0, resultBytes, 0, resultBytes.length);
            return new String(resultBytes, "GBK");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

使用OA系统中存储的所有代码块对工具类做全量测试,确认加解密结果一致。

那么,我们就可以在此基础上,进一步实现代码块内容的查找与批量替换。