最近略微研究了一下证书,为此借着这个东风,顺带研究一下安卓的证书及其使用。
Android使用的是jks证书,这个在TLS初探(2)证书简介中有介绍,和P12证书类似,实际就是将X509证书和私钥打包成一个文件,并且对该文件加上密钥(称为密钥库口令);不仅如此,还进一步对其中的私钥加上密钥(称为密钥口令)。简单来说,如果你需要提取证书文件就需要密钥库口令,如果你需要提取私钥,不仅需要密钥库口令还需要密钥口令。jks的生成命令如下:
keytool -genkey -alias android.keystore -keyalg RSA -validity 36500 -keystore android.keystore
在生成的过程中,就会让你输入DN信息、密钥库口令和密钥口令,如果还不清楚清楚DN信息的,可以回顾一下我的“TLS初探(2)证书简介”。
为了分析jks证书,我们简单暴力点,将jks直接转p12之后,通过openssl提取证书和私钥文件。
(1)android证书jks转p12(会要求输入新的配置文件)
keytool -importkeystore -srckeystore android.keystore -srcstoretype JKS -deststoretype PKCS12 -destkeystore android.p12
(2) 提取证书文件
openssl pkcs12 -in android.p12 -nokeys -out cert.pem
(3) 查看证书文件
openssl x509 -in cert.pem -text
如下所示,可以看出,Android证书实际就是一个自签名证书,还是比较简单的
Android证书的作用简单来说就是用来给APK签名,从而确保APK的签发方无误且没有被篡改。具体我们可以看一下实际的APK解压后的信息,在META-INF下有如下文件:
其中MANIFEST.MF文件打开可以看到,是各个文件的SHA1摘要信息列表,CERT.SF是在MANIFEST.MF的基础上再次进行一次摘要信息,RSA信息即用私钥对CERT.SF文件进行摘要与签名。具体的详细分析可以参考一下Android签名机制之---签名过程详解,具体的签名过程分析的还是相当详细的。
那这样做的目的何在呢?
开发过类似google或百度地图、第三方分享等借助第三方平台的功能应用时,相信大家都填写过类似下面的信息:
对于Android来说,就是“数字签名(证书指纹)+ 包名”的方式,首先证书指纹是什么呢?我们通过keytool可以查看一下证书指纹:
证书指纹其实就是你的jks中X509证书的摘要信息,而你的证书就是应用程序开发者或组织的标识,通过该开发者标识+包名,就可以唯一确认该应用,为此一般第三方平台都是用该方式来确认你的应用,从而提供给你相应的资源或API访问权限。
Android Debug Keystore
之前在开发的时候,一直都是打debug包的时候,使用debug.keystore,而打release包的时候,则使用自己通过keytool生成的证书,具体他们直接有什么差别却一直没有深究,gradle的配置相应的如下所示:
第一个问题: debug.keystore不需要指定storePassword、keyPassword和keyAlias,是否代表debug.keystore这些值都为空呢?答案是否定的,debug.keystore的storePassword和keyPassword默认都为“android”,keyAlias默认为androiddebugkey
第二个问题: debug.keystore和release的keystore就仅仅是上述storePassword、keyPassword和keyAlias的区别吗?答案可能出乎一些人的意料,是的,仅仅就只有这个区别而已。
第三个问题: 既然没什么区别,可以使用同一keystore同时签debug版和release版本吗?可以是可以,但是我个人并不建议真么做,因为不少方类似与ShareSDK,友盟等平台,会提供一些统计数据,依据就是之前说的证书指纹和包名,如果使用同一个,这些统计数据必然会有一些开发或自测时所产生的数据,个人觉得还是区分开来好。
也有一些人debug和release确实是使用了两个keystore文件,但是为了避免第三方应用填写多个证书指纹的麻烦,使用了看似很巧妙的方法(例如:利用grade解决APP release版和debug版签名不同的问题),实际上就是改变了密码和别名信息,X509证书和证书指纹并没有改变,这种做法个人感觉还不如直接用一个release的keystore来签的好;首先,就是我之前说的,debug版本的信息和release版本的统计信息在一些第三方平台上交杂在一起;其次,这个做法不太安全,如果你的debug证书被别人获知,就可以直接利用android默认密码取出其中的证书和私钥,这个就很危险了,就可以盗用你的开发者身份进行APK发布等。