第三方应用怎么获取应用签名证书的hash值
在Android中,获取应用签名证书的SHA256散列值可以通过使用Java的KeyStore
类来完成。以下是一个基本的示例,展示了如何使用Java获取已安装应用的签名证书的SHA256散列值。
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class CertificateUtils {
public static String getSHA256Fingerprint(String alias) {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidCAStore");
keyStore.load(null);
final Certificate cert = keyStore.getCertificate(alias);
if (cert != null) {
if (cert instanceof X509Certificate) {
return getSHA256Fingerprint((X509Certificate) cert);
} else {
return "Not an X509Certificate: " + cert.getClass().getName();
}
} else {
return "Alias not found";
}
} catch (Exception e) {
e.printStackTrace();
return "Error getting SHA256 fingerprint: " + e.getMessage();
}
}
private static String getSHA256Fingerprint(X509Certificate cert) throws CertificateParsingException {
List<byte[]> subjectAltNames = Collections.emptyList();
try {
subjectAltNames = Collections.list(cert.getSubjectAlternativeNames());
} catch (Exception e) { /* ignored */ }
final Collection<? extends Certificate> issuerCerts = Collections.emptySet();
try {
issuerCerts = Collections.list(cert.getIssuers());
} catch (Exception e) { /* ignored */ }
final List<byte[]> issuerDNs = Collections.list(issuerCerts.stream().map(cert -> cert.getSubjectX500Principal().getName()).iterator());
final List<byte[]> subjectDNs = Collections.list(cert.getSubjectX500Principal().getName().split("\\s+"));
final List<byte[]> serialNumbers = Collections.list(cert.getSerialNumber().toString().split("\\s+"));
final List<byte[]> publicKeys = Collections.list(cert.getPublicKey().toString().split("\\s+"));
final List<byte[]> signatureAlgorithms = Collections.list(cert.getSigAlgName().split("\\s+"));
final List<byte[]> validityPeriods = Collections.list(cert.getNotBefore().toString().split("\\s+") + cert.getNotAfter().toString().split("\\s+"));
final List<byte[]> serialNumberParameters = Collections.list(cert.getSerialNumberParameter() == null ? "null" : cert.getSerialNumberParameter().toString().split("\\s+"));
final List<byte[]> signatureParameters = Collections.list(cert.getSignatureAlgorithmParameters() == null ? "null" : cert.getSignatureAlgorithmParameters().toString().split("\\s+"));
final List<byte[]> tbsCertificateContents = Collections.list(cert.getTBSCertificate() == null ? "null" : cert.getTBSCertificate().toString().split("\\s+"));
final byte[] encodedHash = cert.getEncoded(); // this is the raw SHA256 hash of the certificate, but it's not directly useful for fingerprint comparison, see https://github.com/google/certificate-transparency/blob/master/client/ctutil/sha256_hasher.py for a more useful approach
return String.format("%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s", // this is just for display purposes, not for fingerprinting!
subjectAltNames, issuerDNs, subjectDNs, serialNumbers, publicKeys, signatureAlgorithms, validityPeriods, serialNumberParameters, signatureParameters, tbsCertificateContents, encodedHash); // this is just for display purposes, not for fingerprinting!
}
}
1 回答538 阅读✓ 已解决
1 回答543 阅读
1 回答488 阅读
1 回答383 阅读
486 阅读
417 阅读
三方应用可以通过bundleManager.getBundleInfoForSelf()获取自身的应用包信息,其中入参bundleFlags指定所返回的BundleInfo中所包含的信息。
参考代码如下:
signatureInfo.fingerprint是应用签名证书(.cer文件)的SHA256 hash值:
对于hash值,可使用加解密框架的hash算法,目前支持SHA1、SHA224、SHA256、SHA384、SHA512、MD5,参考代码如下:
参考链接
Hash.hash