You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android密钥库签名时隔多日后莫名变更问题咨询

问题:签名密钥哈希值莫名变更

我用自己创建的keystore一直给应用签名,应用内也设置了校验key hash是否变更的逻辑。但今日导出并安装APK后,发现key hash发生了变化——我从未对keystore进行过任何操作,本不应出现这种情况。

相关代码片段:

fun getSHA(context: Context): String {
        val info: PackageInfo
        var message = ""
        try {
            info = context.packageManager.getPackageInfo(context.packageName, PackageManager.GET_SIGNATURES)
            for (signature in info.signatures) {
                if(signature != null){
                    val algo = "SHA256"
                    val md: MessageDigest = MessageDigest.getInstance(algo)
                    md.update(signature.toByteArray())
                    val encode = Base64.encode(md.digest(), Base64.DEFAULT)
                    Log.d(TAG, signature.toCharsString())
                    return String(encode).also {
                        MyLog.d(TAG, "\n\n $it")
                    }
                }
            }
        } catch (e1: PackageManager.NameNotFoundException) {
            message = "$TAG Exception: " + e1.message
        } catch (e: NoSuchAlgorithmException) {
            message = "$TAG Exception: " + e.message
        } catch (e: Exception) {
            message = "$TAG Exception: " + e.message
        }
        return ""
    }
排查与解决思路
  • 确认APK签名文件:导出APK时可能误选了debug keystore或其他签名文件。用命令行验证签名信息:

    jarsigner -verify -verbose -certs your-app.apk
    

    查看输出中的签名主体信息,确认是否与你的正式keystore一致。

  • 修复代码签名遍历逻辑:当前代码直接返回第一个签名,但APK可能存在多签名(如渠道打包添加的额外签名),导致取到的签名索引变化。修改代码打印所有签名的哈希值:

    fun getSHA(context: Context) {
            val info: PackageInfo
            try {
                info = context.packageManager.getPackageInfo(context.packageName, PackageManager.GET_SIGNATURES)
                for ((index, signature) in info.signatures.withIndex()) {
                    val algo = "SHA256"
                    val md: MessageDigest = MessageDigest.getInstance(algo)
                    md.update(signature.toByteArray())
                    val encode = Base64.encode(md.digest(), Base64.DEFAULT)
                    val hash = String(encode).trim()
                    Log.d(TAG, "签名[$index]哈希值: $hash")
                }
            } catch (e: Exception) {
                Log.e(TAG, "Exception: ${e.message}")
            }
        }
    

    运行后对比日志,确认之前校验的哈希值对应哪个签名。

  • 检查构建配置:查看build.gradle中的signingConfigs配置,确认是否被修改;同时检查打包时是否选错了build variant(比如误选了非release变体)。

  • 验证keystore完整性:用命令行查看keystore的密钥指纹,确认与之前记录的一致:

    keytool -list -v -keystore your-keystore.jks
    
  • 统一Base64编码规则:代码中使用Base64.DEFAULT会自动添加换行符,导致哈希值末尾多了换行。对比时可以先去除换行符,或改为Base64.NO_WRAP编码,避免格式差异。

内容的提问来源于stack exchange,提问作者Himanshu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 15:25:34