/** Sign data and write the digital signature to 'out'. */
private static void writeSignatureBlock(
CMSTypedData data, X509Certificate publicKey, PrivateKey privateKey,
OutputStream out)
throws IOException,
CertificateEncodingException,
OperatorCreationException,
CMSException {
ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>(1);
certList.add(publicKey);
JcaCertStore certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner signer = new JcaContentSignerBuilder(getSignatureAlgorithm(publicKey))
.setProvider(sBouncyCastleProvider)
.build(privateKey);
gen.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder()
.setProvider(sBouncyCastleProvider)
.build())
.setDirectSignature(true)
.build(signer, publicKey));
gen.addCertificates(certs);
CMSSignedData sigData = gen.generate(data, false);
ASN1InputStream asn1 = new ASN1InputStream(sigData.getEncoded());
DEROutputStream dos = new DEROutputStream(out);
dos.writeObject(asn1.readObject());
}
可以看到代码使用了CMSSignedDataGenerator类去生成.RSA文件,根据CMSSignedDataGenerator的说明文档描述:"general class for generating a pkcs7-signature message",可知该类是用来生成PKCS7签名信息的,所以生成的CERT.RSA遵循PKCS#7标准,PKCS#7文件格式如下(使用ASN.1语法)
本文介绍获取签名.apk文件的证书的几种方式,重点介绍从.RSA文件中获取
1. 使用keytool工具从keystrore文件中获取
$ keytool -export -alias key0 -file my.cer -keystore my.jks
2. 调用Android API
3. 从.RSA文件中获取
将被签名过的.apk文件解压即可得到/META-INF/CERT.RSA文件,接下来我们需要分析CERT.RSA是什么格式文件,里面包含什么信息。
通过阅读Android源码SignApk.java 中生成.RSA的代码段
可以看到代码使用了CMSSignedDataGenerator类去生成.RSA文件,根据CMSSignedDataGenerator的说明文档描述:
"general class for generating a pkcs7-signature message"
,可知该类是用来生成PKCS7签名信息的,所以生成的CERT.RSA遵循PKCS#7标准,PKCS#7文件格式如下(使用ASN.1语法)可以看到PKCS7中包含了证书(certificates)
如何从PKCS#7文件中获取证书呢,这里介绍使用openssl command方式和openssl api方式
openssl command
$ openssl pkcs7 -inform DER -in CERT.RSA -print_certs | openssl x509 -outform DER -out CERT.cer
openssl api
最终放几张输出截图证明这几种方式提取的证书内容是一样的
Android API
keytool
openssl command
使用openssl api
参考: Android中的签名和签名文件的生成过程 how to Read the certificates file from the PKCS7.p7b certificate file usind openssl? Regarding: PKCS7, X509 and DER
拓展阅读: getting apk signature outside of android