【问题标题】:is Signature.hashCode referring to the right hashCode?Signature.hashCode 是指正确的 hashCode 吗?
【发布时间】:2020-02-26 22:17:20
【问题描述】:

下面的代码 (sign.hashCode()) 是给我签名的 hashCode 还是内存中对象的哈希?

try {
    PackageInfo packageInfo = getPackageManager().getPackageInfo(
            "com.klxx.as", PackageManager.GET_SIGNATURES);
    Signature[] signs = packageInfo.signatures;
    Signature sign = signs[0];
    Log.i("test", "hashCode : "+sign.hashCode());
} catch (Exception e) {
    e.printStackTrace();
}

文档 (here) 只说以下内容,与任何其他对象一样。

此对象的哈希码值。

但是我在多个网站上看到上面的 sn-p 声称它显示了 apk 的标志。其他一些来源也使用签名字节自己创建哈希。

【问题讨论】:

    标签: android signature


    【解决方案1】:

    虽然其他答案在技术上是正确的,但在其他方面它们是危险的错误

    是的Signature.hashCode()is overwritten 并且确实在签名的字节上计算了一些弱的 32 位哈希值,这使其具有确定性。

    但是,您不应该将此值用作任何类型的信任决策的基础,如果您首先检索签名,通常希望这样做。这是因为为hashCode() 生成具有相同值的伪造签名非常容易:只需生成2^32 随机签名证书就可以很好地发现冲突并且非常可行。

    改为,您应该使用加密安全的哈希函数,例如 SHA-256 和 e.g.将生成的哈希转换为 Base64:

    MessageDigest digest = MessageDigest.getInstance("SHA-256");
    byte[] hashBytes = digest.digest(sign.toByteArray());
    String hash = Base64.encodeToString(hashBytes, Base64.NO_WRAP);
    

    【讨论】:

    • 您的意思是,我需要将生成的哈希值与从 keytool 命令获得的 SHA256 值进行比较?如果我的 SHA256 是“BB:FD:64:F5:1D:8B:2F:F8:34:83:55:5B:22:E9:D7:53:D0:5B:AA: 7C:9E:D9:E6:92:02:60:48:48:28:B3:68:3D"?
    • @Jenix 我上面包含的代码 sn-p 将为您提供以 Base64 编码的 SHA-256 哈希。以相同的方式编码,您提供的哈希将如下所示:gchq.github.io/CyberChef/…。然后您可以比较结果字符串。
    • 是的,我需要将我的指纹编码为 Base64,但是当我在这里发表评论时,我正在寻找一种将您的 Base64 值编码为十六进制值的方法。傻我!还是谢谢你:)
    • @Jenix 虽然 Base64 在 Android 上很容易使用,但转换为十六进制字符串的便捷方法似乎需要额外的依赖项。
    • 您好!对于我在本地构建和测试的 APK 文件,此检查效果很好。但是我从 Google Play 商店下载的 AAB 文件(当然是我上传的)未能通过此检查,因此我不得不关闭此功能。是因为 Google Play 服务器对我的 AAB 做了什么吗?那我不能对在 Google Play 上发布的应用使用这种方法吗?
    【解决方案2】:

    Signature.hashCode() 被覆盖,在这种情况下是根据签名字节数组的内容计算的。

    可以看源码解决你的疑惑http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/content/pm/Signature.java#Signature.hashCode%28%29

    【讨论】:

    • 虽然这在技术上是正确的,但如果没有以下大警告就离开它是危险的: hashCode() 的返回值是一个非加密安全的 32 位散列,不应该用于验证包的签名。有关详细信息,请参阅下面的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 2014-02-05
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    相关资源
    最近更新 更多