• 混淆技术研究笔记(四)反篡改介绍


    logo
    先来看看AI的介绍,为了防止Java代码打包的JAR包被篡改,可以采取以下几种措施:

    1. 使用数字签名:可以使用Java的签名工具(如Jarsigner)对JAR包进行数字签名。签名可以确保JAR包的完整性和来源可信性。在验证JAR包时,可以使用Java的验证工具(如Jarsigner或Java Web Start)来验证签名。

    2. 使用加密技术:可以使用加密算法对JAR包进行加密,确保只有授权的用户才能解密和使用JAR包。可以使用Java的加密库(如javax.crypto)来实现加密和解密操作。

    3. 使用文件校验和:可以使用文件校验和算法(如MD5或SHA-256)计算JAR包的校验和,并将校验和值保存在可信任的位置(如服务器)。在使用JAR包时,可以重新计算校验和并与保存的值进行比较,以验证JAR包的完整性。

    4. 使用安全沙箱:可以使用Java的安全沙箱机制来限制JAR包的访问权限,防止恶意代码对系统进行篡改或攻击。可以使用Java的安全管理器(SecurityManager)来配置和管理安全沙箱。

    5. 使用代码混淆:可以使用代码混淆工具对Java代码进行混淆,使代码难以阅读和理解。混淆后的代码更难被篡改和逆向工程。

    综合使用上述措施可以提高JAR包的安全性,减少被篡改的风险。然而,完全防止JAR包被篡改是很困难的,因此还应定期更新和验证JAR包,以及采取其他安全措施来保护系统的安全。


    前面我们已经对代码进行了混淆,想修改代码是很难的,如果我们打包包含的代码很多,为了功能的完整性,我们可能会要求核心代码不允许被覆盖,被混淆的代码通过某些工具还是可以改名的,比如把超长的名字改短,然后再覆盖代码,有很多手段能绕过,为了再增加一些难度,本文考虑使用RSA对称加密对混淆后的代码进行加密,不允许修改混淆后的类名,不允许修改文件内容。

    使用hutool提供的RSA可以很简单的生成私钥和公钥,可以很方便的加解密,下面是示例代码:

    RSA rsa = new RSA();
    PrivateKey privateKey = rsa.getPrivateKey();
    PublicKey publicKey = rsa.getPublicKey();
    String home = System.getProperty("user.home");
    String privateKeyPath = home + File.separator + ".yguard" + File.separator + "license-keys.pri";
    String publicKeyPath = home + File.separator + ".yguard" + File.separator + "license-keys.pub";
    if (!new File(privateKeyPath).exists()) {
        FileUtil.writeBytes(privateKey.getEncoded(), privateKeyPath);
        FileUtil.writeBytes(publicKey.getEncoded(), publicKeyPath);
        String publicKeyHex = HexUtil.encodeHexStr(publicKey.getEncoded());
        FileUtil.writeString(publicKeyHex, publicKeyPath + ".hex", StandardCharsets.UTF_8);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    通过上面的代码将私钥和公钥生成到用户目录下面的 .yguard 目录中。

    这里还将公钥生成了一个16进制字符串形式的文本,方便直接签入到解密程序中使用。

    可以使用下面的方法进行加密和解密:

    /**
      * 使用私钥加密
      */
     private static String encryptHex(String str) {
         String home = System.getProperty("user.home");
         String privateKeyPath = home + File.separator + ".yguard" + File.separator + "license-keys.pri";
         RSA rsa = new RSA(FileUtil.readBytes(privateKeyPath), null);
         byte[] bytes = rsa.encrypt(str, StandardCharsets.UTF_8, KeyType.PrivateKey);
         return HexUtil.encodeHexStr(bytes);
     }
    
     public static final String PUB_KEY = "****很长的公钥,使用上面生成后的内容替换****";
    
     /**
      * 使用公钥解密
      */
     private static String decryptStr(String str) {
         RSA rsa = new RSA(null, HexUtil.decodeHex(PUB_KEY));
         return rsa.decryptStr(str, KeyType.PublicKey, StandardCharsets.UTF_8);
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    使用下面代码进行简单测试:

    public static void main(String[] args) {
        String url = "https://mybatis.io";
        System.out.println("原始: " + url);
        String sign = encryptHex(url);
        System.out.println("加密: " + sign);
        String str = decryptStr(sign);
        System.out.println("解密: " + str);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    输出内容如下:

    原始: https://mybatis.io
    加密: 8d13070b469768ea57cef0800ed9be4e3e6303ad10cbd308ed9d959ea4caace0d2c17b020af33bca563aa0f45e1b4e8a82bbc4ee67fbb80bc26f5da5c24865fb851ed5c4868631bde5f324213b77a432fa40a761412bb5ac3b380ea4f07496665369b9076bc2091f3707fe4b0c0e1a337394736085a2198f2ff82d3ba06eff19
    解密: https://mybatis.io
    
    • 1
    • 2
    • 3

    有了这些工具后,我们就需要考虑如何在混淆后的代码上增加加密签名防止混淆了。

  • 相关阅读:
    SQL Prompt10 安装激活教程,让你写sql 如鱼得水
    Tensor.scatter_add_函数解释:
    在 macOS 上安装 Rust 开发环境并运行第一个程序的详细步骤
    2022第三届“网鼎杯”网络安全大赛-青龙组 部分WriteUp
    【Kettle】Kettle部署与运行
    LeetCode-高频 SQL 50 题:查询 篇
    【PTA-训练day3】L2-014 列车调度 + L1-009 N个数求和
    Windows OpenGL ES 图像曝光度调节
    微信小程序自动化采集方案
    Open3D 进阶(9)使用BCPD算法对点云配准
  • 原文地址:https://blog.csdn.net/isea533/article/details/133323592