简体   繁体   English

如何获得APK签名签名?

[英]How to get APK signing signature?

Is there a way to retrieve the signature of the key used to sign an APK?有没有办法检索用于签署 APK 的密钥的签名? I signed my APK with my key from my keystore.我用我的密钥库中的密钥签署了我的 APK。 How can I retrieve it programmatically?如何以编程方式检索它?

You can access the APK's signing signature like this using the PackageManager class http://developer.android.com/reference/android/content/pm/PackageManager.html您可以像这样使用 PackageManager 类访问 APK 的签名签名http://developer.android.com/reference/android/content/pm/PackageManager.html

Signature[] sigs = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
for (Signature sig : sigs)
{
    Trace.i("MyApp", "Signature hashcode : " + sig.hashCode());
}

I've used this to compare with the hashcode for my debug key, as a way to identify whether the APK is a debug APK or a release APK.我用它来与我的调试密钥的哈希码进行比较,以此来识别 APK 是调试 APK 还是发布 APK。

The package manager will give you the signing certificate for any installed package.包管理器将为您提供任何已安装包的签名证书。 You can then print out the details of the signing key, eg然后您可以打印出签名密钥的详细信息,例如

final PackageManager packageManager = context.getPackageManager();
final List<PackageInfo> packageList = packageManager.getInstalledPackages(PackageManager.GET_SIGNATURES);

for (PackageInfo p : packageList) {
    final String strName = p.applicationInfo.loadLabel(packageManager).toString();
    final String strVendor = p.packageName;

    sb.append("<br>" + strName + " / " + strVendor + "<br>");

    final Signature[] arrSignatures = p.signatures;
    for (final Signature sig : arrSignatures) {
        /*
        * Get the X.509 certificate.
        */
        final byte[] rawCert = sig.toByteArray();
        InputStream certStream = new ByteArrayInputStream(rawCert);

        try {
            CertificateFactory certFactory = CertificateFactory.getInstance("X509");
            X509Certificate x509Cert = (X509Certificate) certFactory.generateCertificate(certStream);

            sb.append("Certificate subject: " + x509Cert.getSubjectDN() + "<br>");
            sb.append("Certificate issuer: " + x509Cert.getIssuerDN() + "<br>");
            sb.append("Certificate serial number: " + x509Cert.getSerialNumber() + "<br>");
            sb.append("<br>");
        }
        catch (CertificateException e) {
            // e.printStackTrace();
        }
    }
}

My situation is that I have a pre-installed apk which use a wrong key-store .我的情况是我有一个预装的 apk,它使用了错误的 key-store 。 So directly install will give a fail because of inconsistent signature.I need to check the signature first to make sure it can be install smoothly.所以直接安装会因为签名不一致而失败。我需要先检查签名以确保它可以顺利安装。

Here is my solution .这是我的解决方案

As this code says, you can get the signature from an installed apk.正如这段代码所说,您可以从已安装的 apk 中获取签名。

details:细节:

Signature sig = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0];

Secondly: get the releaseApk hashCode to compare.其次:获取 releaseApk hashCode 进行比较。 In my case, I downloaded this apk from my server, and put it in the sd_card.在我的例子中,我从我的服务器下载了这个 apk,并将它放在 sd_card 中。

Signature releaseSig = context.getPackageManager().getPackageArchiveInfo("/mnt/sdcard/myReleaseApk.apk", PackageManager.GET_SIGNATURES).signatures[0];

Finally,compare the hashCode.最后,比较hashCode。

return sig.hashCode() == releaseSig.hashCode;

I have tried the code above, it works just fine.我试过上面的代码,它工作得很好。 If the hashCode is different, you should just uninstall the old apk or if it's a system app and the device is rooted, you can just use runtime to remove it ,and then install the new signature apk.如果hashCode不同,你应该卸载旧的apk,或者如果它是一个系统应用程序并且设备已经root,你可以使用runtime删除它,然后安装新的签名apk。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM