移动应用安全和证书相关知识总结


数据在互联网上分发,就会涉及到数据安全问题,主要包括

  1. 防止数据泄露 - 加密
  2. 防止数据被篡改 - 数字签名
  3. 防止数据调包 - CA证书

加密

对称加密(AES/DES)

优点: 算法公开、计算量小、加密速度快、加密效率高
缺点:加解密密钥是一个,密钥如何安全保存是个难题,或者说,是潜在的风险点

非对称加密(RSA等)

对应密钥和公钥,使用密钥加密,通过公钥解密,反之也是

优点:安全,公钥可以放出,只要保存好私钥就好了
缺点:速度较慢

DES由于key不能安全保存,在公开发行的数据或文件,只能用RSA,但是RSA加密效率不行,而且对于很多非机密数据,我们其实不需要绝对的加密隐藏,只需要有机制保证其在传输过程中不被修改即可,这就需要数字签名了

数字签名

数字签名步骤:

  1. 使用hash算法生成数据的信息摘要
  2. 使用私钥对摘要加密,生成数字签名
  3. 将数据+数字签名+证书(公钥)一起发给接受方

接受方在收到后,先用证书里的公钥对数字签名解密,接着使用同样的hash算法生成数据的hash值,再与解密后的数据对比,如果一致,说明数据没被修改过

数字证书

证书包含如下信息:

  1. 证书拥有者的信息
  2. 证书拥有者的公钥
  3. 证书签名数据(基于证书发行机构的RSA私钥对1和2包含信息对应hash摘要加密后的数据)
  4. 证书指纹,基于证书内部的数据(上述1,2,3)生成的endcoded值,能够唯一标识该证书
  5. 证书签发者信息

证书的有效性验证,在拿到证书后,会通过证书发行机构的RSA公钥对证书签名数据解密,然后再用相同的hash算法,生成1+2的hash摘要,再跟解密后的指纹数据对比,如果是一致的,说明证书是有效的,再根据证书中拥有者的信息,来判定证书来源的正确性

通过上面我们可以知道,只要证书发行结构是值得信任的,那证书的完整性就是值得信任的,那对应的证书拥有者和公钥数据,就不存在中途被调包的风险,那数据在整个传输过程就是绝对安全的

证书文件格式一般都为 X509

自签名证书和CA证书

什么是自签名证书,就是证书签名数据的生成,使用了个人的RSA私钥生成的,这会有两个风险:

  1. 证书拥有者信息的准确性,是没办法保证的,因为可以随便填
  2. 接受方拿到自签名证书后,没办法做证书校验,因为指纹是基于个人RSA私钥生成的,接收方没有对应的公钥,指纹数据无法读取,自然无法对证书有效性做验证

所以,自签名证书,可以在学习的时候用用,正式的业务上,必须使用由权威结构颁发的证书,这就是CA证书的由来

CA证书在对客户证书签名时,客户首先提交待签名的证书,CA机构会验证客户信息的正确性和唯一性,然后再基于CA机构的RSA私钥对客户证书签名,生成CA证书

一般浏览器和操作系统,都会保持有CA的根证书,所以默认就可以对客户的CA证书做有效性验证

证书链

CA证书有3类:

  1. end-user :baidu.com 包含用来加密传输数据的公钥的证书,是HTTPS中使用的证书
  2. intermediates:CA用来认证公钥持有者身份的证书,即确认HTTPS使用的end-user证书是属于baidu.com的证书。这类intermediates证书甚至可以有很多级。
  3. root:用来认证intermediates证书是合法证书的证书。

添加intermediates颁发机构,是为了增加安全性,毕竟增加几级缓冲,让root私钥守在底处,让intermediates去面对各个客户,出问题的概率会大大的降低,万一某个intermediates出问题了,也只需要解除这个intermediates的信任就行了

证书链的原理也很简单,就是end-user可以通过intermediates来做证书校验,intermediates证书,也可以通过另一个intermediates校验,只要这个校验链,最终走到root根证书就行了,只要这个证书链上的证书,全部校验通过,那end-user的证书,就是可信的,反之,中途的任何一个校验不过,证书链中断,end-user不可信

如果你的CA证书是通过intermediates颁发的,有一点需要注意,就是接受校验方,是否拥有intermediates证书,因为CA根证书,就像上面说的浏览器和系统底层,都是预置的,如果intermediates没有,会导致链式校验中断,如果是https,需要在服务端做intermediates下载相关信息的配置

私钥,公钥和证书如何保存?

JKS(JavaKeysotre)格式和PFX(PKCS12)格式,是最常见的SSL证书格式文件,可以包含完整的证书密钥对,证书链和信任证书信息。

android源自java,所以一般都用JKS,ios则为.p12, PKCS12是行业标准格式,现在android生成.jks时,也会提示转换成PKCS12

两种格式得读取,都可以通过Java得 KeyStore来完成,具体代码参考#证书指纹#内的代码

证书指纹

基于证书内部数据生成,作为证书的标识,可以通过如下代码获取:

        String jksPath = ""; //jks file path
        String jksPassword = ""; // jks keyStore password
        String certAlias = ""; // cert alias
        String certPassword = ""; // cert password
        KeyStore keyStore = null;

        try {
            keyStore = KeyStore.getInstance("JKS");
            keyStore.load(new FileInputStream(jksPath), jksPassword.toCharArray());
            PrivateKey privateKey = (PrivateKey) keyStore.getKey(certAlias, certPassword.toCharArray());

            X509Certificate cert = (X509Certificate) keyStore.getCertificate(certAlias);
            PublicKey publicKey = keyStore.getCertificate(certAlias).getPublicKey();
            //证书的encoded值的md5,即为指纹
            System.out.println("11 = " + shaEncode(cert.getEncoded()));
        } catch (KeyStoreException e) {
        }

所以,证书内部的任何参数变了,对应的encoded值肯定会变,对应的指纹数据也会变

还可以通过如下命令查看证书数据:
keytool -list -keystore debug.keystore
keytool -printcert -file META-INF/CERT.RSA

Android & IOS安装包签名

安装包在发布前,必须使用上述所说得SSL证书签名,android是.jks文件,ios则是.p12,目的当然也是上面说得:

  1. 利用私钥对zip包内的文件生成签名文件,从而保证安装包数据的完整性
  2. 基于数字证书来验证包得来源

由于android用的证书都是开发者自行创建并签名的自签名证书,所以系统安装时就无法对安装包得来源校验,只能利用证书的唯一性,针对证书指纹得对比,来避免app被非法替代安装

Android的V1和V2签名,原理是一致的,不同的是,签名数据和证书存放位置的不同:

  1. V1,会对除META-INF之外的所有文件生成hash,保存到MANIFEST.MF, 然后基于MANIFEST.MF内的数据,生成签名数据CERT.SF, 并将证书文件保存到.RSA
  2. V2,直接对整个apk包做hash并生成签名数据,并将签名和证书数据保存到zip的一个section里头

哪个好?肯定是V2,V1由于META-INF目录下是不做校验的,所以发布包解压后,可以随便往这个目录下扔东西,还有,V1是基于zip内每个文件生成hash的,读取文件时,会做二次校验,会存在一部分的性能损耗

V2直接对整包做校验,发布后,就不能做任何修改了,而且读取文件时也不需要二次校验,所以性能会好点

IOS由于证书是经过苹果官方认证签名的,证书,开发者账号等等信息都存在苹果服务器,如果谁对app二次打包,安装时会校验失败

简单点说就是,android是自签名证书,可以二次打包后安装,前提是系统没有冲突得应用存在,ios由于是官方得签名证书,无法二次打包,因为安装得时候,系统会做证书信息校验

参考文献

java读取jks公钥私钥
https://www.jianshu.com/p/a3b3cca98b06

Android V1及V2签名原理简析
http://www.jintiankansha.me/t/pNV38Zd4Ne

常见数字证书类型和代码解析
https://www.cnblogs.com/xq1314/archive/2017/12/05/7987216.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值