【问题标题】:Protect APK from resigning with different keystore保护 APK 免于使用不同的密钥库退出
【发布时间】:2022-01-22 21:22:09
【问题描述】:

我刚刚使用 apkTool 反编译了我签名的 apk,并使用相同的反编译类文件夹使用不同的密钥库重新签名了新的 apk。然后尝试在我的设备中安装并用新的 apk 覆盖旧的 apk,它工作正常。

但是现在我不希望这个 apk 被不同的密钥库辞职。如果有人用不同的密钥库辞职,那么它不应该被旧的覆盖,或者它不应该被安装。

创建新签名 apk 的命令:

1. java -jar apktool.jar d test.apk
2. java -jar apktool.jar B test
3. keytool -genkey -v -keystore testrelease.keystore -alias testrelease -keyalg RSA -keysize 2048 -validity 10000
4. jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore testrelease.keystore test_1.apk testrelease

注意:这里我没有使用 playstore 来部署 apk,我只是通过邮件共享 apk 直接在我的设备中进行部署。

【问题讨论】:

    标签: android apk android-keystore apktool signed-apk


    【解决方案1】:

    我认为您无法阻止您的应用退出。没有什么是100%安全的。 尽管您可以在运行时验证应用程序的签名,并在签名与原始签名不匹配时执行一些操作。不过这个验证码也可以在反编译apk后轻松删除。

    使用它来验证签名:

    try {
    
        Signature[] arrSignature;
        PackageInfo signatureInfo;
        SigningInfo signingInfo;
        String SIGNATURE = "Your original signature";
        PackageManager packageManager = this.getPackageManager();
    
        if(Build.VERSION.SDK_INT < 28) {
    
          signatureInfo = packageManager.getPackageInfo("package name",PackageManager.GET_SIGNATURES);
          arrSignature =  signatureInfo.signatures;
    
        }else {
    
          signingInfo = packageManager.getPackageInfo("package name",PackageManager.GET_SIGNING_CERTIFICATES).signingInfo;
          arrSignature = signingInfo.getApkContentsSigners();
    
        }
    
        for(Signature sig : arrSignature){
           final byte[] rawCert = sig.toByteArray();
           InputStream certStream = new ByteArrayInputStream(rawCert);
    
           MessageDigest md5,sha1,hash,sha256;
           md5 = MessageDigest.getInstance("MD5");
           hash = MessageDigest.getInstance("SHA");
           sha1 = MessageDigest.getInstance("SHA1");
           sha256 = MessageDigest.getInstance("SHA256");
           md5.update(rawCert);
    
           hash.update(rawCert);
           sha1.update(rawCert);
           sha256.update(rawCert);
    
           String hash_key = new String(Base64.encode(hash.digest(), 0));
    
           if (SIGNATURE.equals(hash_key)){
                   //Valid Signature
           }
           else {
                  // Invalid Signature
               }
           }
    }catch (CertificateException | NoSuchAlgorithmException | PackageManager.NameNotFoundException e) {
                    e.printStackTrace();
             }
     }
    

    您可以比较任何您想要的签名(MD5、SHA1、SHA256),这里我只是比较了应用程序的“sha”。

    【讨论】:

    • 我可以在我的代码中添加一个检查,它可以识别 apk 是否已使用不同的证书退出。这样我就可以阻止那些新签名的 apk 用户访问我的应用程序。
    • 是的,您可以,您必须将原始证书存储在应用程序中,并与您在运行时获得的证书进行检查。这个技巧不是很有效,因为任何人都可以删除您验证签名的代码。
    • 谢谢@DrHowdyDoo,没错。但我仍然需要尝试一下。能否请您提供该检查的代码 sn-p。
    • 是的,让我在答案中添加它
    猜你喜欢
    • 2021-12-11
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 2011-02-01
    • 1970-01-01
    相关资源
    最近更新 更多