把一些常见的 Key 相关的内容列在这,便于之后理解。
1. JKS (Java KeyStore) 和 PFX (pkcs12) 都是常见的密钥库的格式,用于保存完整的证书密钥对,证书链和信任证书信息,前者是 Sun 制定的,适用于 Java 世界,比如 Tomcat,Geronimo,Websphere 等,后者"据说"常用于 IIS (没配置过) 等。JKS 相关的工具是 JDK 带的 keytool,PFX 可以使用 openssl。
2. JKS 中有存放的内容常见有两类,一个是 PrivateKeyEntry, 包含了完整的证书密钥对,证书链等信息,另外一个是 trustedCertEntry, 包含受信公钥信息。可以使用 keytool -list -keystore 显示。
3. 一般使用工具生成 RSA 非对称密钥对之后,还会由第三方机构 (CA) 生成签名,用于标识密钥所有者的身份,所以通常我们会说,我们将证书下发给客户端,此时的证书包括如下信息,公钥,签名信息等。
4. 使用 JKS 存储信息时,由于 Keystore 中可以存放多个密钥信息,所以通过会使用 alias 标识,需要使用时,需要指定别名。另外,Keystore 本身可以使用 storepassword 保护,而针对每一个 key,也可以是使用 keypassword 保护。
5. keytool 支持导入公钥和其他 keystore,暂不支持导入 PrivateKeyEntry,此时若手中有私钥和证书两个信息,只能先倒入到 PFX 中,再导入到 JKS 中。
openssl pkcs12 -export -in [my_certificate.crt] -inkey [my_key.key]
-out [keystore.p12] -name [new_alias] -CAfile [my_ca_bundle.crt] -caname
root
keytool -importkeystore -deststorepass [new_keystore_pass]
-destkeypass [new_key_pass] -destkeystore [keystore.jks] -srckeystore
[keystore.p12] -srcstoretype PKCS12 -srcstorepass
[pass_used_in_p12_keystore] -alias [alias_used_in_p12_keystore]
6. JAR 签名,主要是在 META-INF 目录下,除了 MANIFEST.MF 之外,还有 *.SF 和 *.RSA 文件 (后缀随签名使用的算法会略有不同), MF 保存了 JAR 中每个文件的散列信息,一般使用 MD5 或者 SHA-1
Name: AndroidManifest.xml
SHA-256-Digest: vn9XTNvoXBMgbaxUqDoc4WUsWseMfRCQQRSR87+F/Hc=
SF 文件使用 RSAwithSHA1, 针对 MF 中的每条信息再次生成签名信息,另外针对整个 MF 也会生成签名信息。
Name: AndroidManifest.xml
SHA-256-Digest: Pa/g6cA3KpnfBvCD/mgnyczjfLCSkAv2l9A+EVxaJlg=
RSA 中是前述签名所用证书等相关信息
通常我们在读取 Jar 文件的每个 Entry 时,如果 META-INF 目录下有如上文件,会做签名验证,因为散列信息计算需要读取文件内容,所用在调用 getCertifcate 方法时,需要读一下流里面的内容,如果只是验证的目的,读取直接忽略即可,考虑读取性能,可以指定 byte[] buffer 的大小,使用流的 skip 方法时,内部 ZipInputStream 中使用的是
private byte[] tmpbuf = new byte[512];
7. 一般而言,证书有两种常见用途,一是用于传输加密,主要是 SSL,另外一个对文件进行签名,比如 JarFile 相关,而 CA 颁发证书时,会在证书中指定其用途,从目前看,以上两种不会同时生效,即若此证书声明为用于 SSL,则无法用于对 JarFile 进行签名,实际使用会发现 JarSign 时未显示错误,但通过 JarEntry 获取证书时一直为空。