Android 在运行时检查应用程序发布签名——鸡和蛋?

Android 在运行时检查应用程序发布签名——鸡和蛋?,android,security,release,signature,Android,Security,Release,Signature,我正在尝试在运行时检查我的应用程序的发布签名,以防止篡改。然而,我一直在读的是,我需要在运行期间记录签名,以便将其硬编码到我的应用程序中进行运行时比较。但我认为这有两个问题: 1) 调试(读取日志)时获得的签名将不同于发布签名。 2) 如果我得到了发布签名,然后将其放入代码中进行运行时比较,这不会改变下一个发布版本的签名吗。。。因此就出现了鸡和蛋的问题? 我错过了什么?静态最终字符串不会更改签名吗?同样,如果我记录发布输出,日志代码是否不会更改签名?什么影响和不影响发布签名?如果通过包含签名本身

我正在尝试在运行时检查我的应用程序的发布签名,以防止篡改。然而,我一直在读的是,我需要在运行期间记录签名,以便将其硬编码到我的应用程序中进行运行时比较。但我认为这有两个问题: 1) 调试(读取日志)时获得的签名将不同于发布签名。 2) 如果我得到了发布签名,然后将其放入代码中进行运行时比较,这不会改变下一个发布版本的签名吗。。。因此就出现了鸡和蛋的问题?
我错过了什么?静态最终字符串不会更改签名吗?同样,如果我记录发布输出,日志代码是否不会更改签名?什么影响和不影响发布签名?

如果通过包含签名本身的字节计算签名,那么是的,您将遇到鸡和蛋的问题。但是你不必:计算签名,除了签名。事实上,
jarsigner
就是这样生成签名的

但是我认为您真正想要的是,因为apk文件已经签名,检查签名者信息是否与您自己的匹配。这可以通过比较包的签名者证书和您自己的证书来实现


您可以从中看到执行此类检查的已采用示例。

如果我要更改您的apk,请执行以下步骤:

  • 用解压程序打开apk
  • 从中获取一到两个资源(例如:类文件)
  • 对其进行更改(de copmile、更改、重新编译)
  • 把它放回APK
  • 签字
  • 发表
  • 在第5步我会遇到一些问题,因为我没有你的私钥和签名,我应该创建自己的私钥并用我的密钥签名。然后,我希望在安装应用程序之前没有人检查标志(没有人这样做!)

    因此,我被篡改的应用程序与您的应用程序有两个不同之处:更改的资源和更改的签名证书

    如果您想检查已更改的资源(签名超过字节),您将遇到鸡和蛋的问题

    阻止我的最简单方法是硬编码你的应用程序签名,并检查它是否在运行时更改

    示例代码位于

    此检查的一种简单方法:

    private boolean validateAppSignature() {
            APP_SIGN= "f10e2821bbbea527ea02200352313bc059445190";
            PackageInfo packageInfo = this.getPackageManager().getPackageInfo(
                        getPackageName(), PackageManager.GET_SIGNATURES);
            for (Signature signature : packageInfo.signatures) {
                // SHA256 the signature
                String AppSign = DigestUtils.sha256Hex(signature.toByteArray());
                return APP_SIGN.equalsIgnoreCase(AppSign);
            }
            return false;
        }
    

    当然,这不是一个100%的解决方案,即使模糊代码可以更改。所以我可以想办法绕过这张支票。但是您让我更难篡改:)

    那么,这是否意味着您提供链接的代码不会通过添加以下行来更改签名:private static String CERTIFICATE_SHA1=“DD1C1115D3E2CB99AB05F98F0C8190E16FDDA4C7”;如链接中所列?换句话说,更新SHA1代码不会改变结果签名吗?
    CERTIFICATE\u SHA1
    常量是您用于对应用程序存档进行签名的证书的指纹。它是常量,只要使用相同的证书,它不会随每次签名而更改。