证书番外篇之Android证书

       最近略微研究了一下证书,为此借着这个东风,顺带研究一下安卓的证书及其使用。

       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证书的作用

       Android证书的作用简单来说就是用来给APK签名,从而确保APK的签发方无误且没有被篡改。具体我们可以看一下实际的APK解压后的信息,在META-INF下有如下文件:

       其中MANIFEST.MF文件打开可以看到,是各个文件的SHA1摘要信息列表,CERT.SF是在MANIFEST.MF的基础上再次进行一次摘要信息,RSA信息即用私钥对CERT.SF文件进行摘要与签名。具体的详细分析可以参考一下Android签名机制之---签名过程详解,具体的签名过程分析的还是相当详细的。

       那这样做的目的何在呢?

  1. 首先当应用程序安装的时候,会通过证书中的公钥信息去解CERT.RSA中的签名信息,得到CERT.SF的摘要,在与CERT.SF的摘要信息对比,确认两者一致。如果不一致,由于使用非对称加密进行签名,为此只可能要么是文件摘要信息不正确(可能有文件被修改),或者是加密私钥不正确(可能是自行签名了别人的APK导致的)。这样可以保证CERT.SF中的摘要信息正确无误。
  2. 在CERT.SF确认无误的基础上,就可以进一步确认MANIFEST.MF文件也是准确的(SHA摘要算法不可逆),再通过MANIFEST.MF检查每一个文件的摘要信息,确认没有被修改,从而保证了整个APK未被篡改。

证书指纹的作用

      开发过类似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发布等。

发布了42 篇原创文章 · 获赞 9 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/jjxojm/article/details/81395573