Android 学习笔记 —— APK 签名

【Android 知识笔记】

---------【APK 签名】---------
目的:确保包体的准确性及真实性,防止包体内容被修改
原因:签名相当于在包体内内置一个唯一、固定的字符串,只有字符串一致的情况下,才认为这个 APK 未经过修改

1. 基本概念:
- 数字摘要:任意长度的数据,都能通过 hash 算法得到一个固定长度的二进制数据,这个数据称为”摘要“
    - 特点:
        1. 唯一性:在不产生数据碰撞(即数据量太大时可能两个不同的数据生成相同的 hash 值)的情况下,不同数据的摘要是不同的
        2. 固定长度:不同 hash 算法的长度不一样,但是相同 hash 算法计算后的结果的长度肯定是一致的
            - MD5:128位长度
            - SHA1:160位长度
        3. 不可逆性:根据摘要无法逆向还原出原始数据
        
    - 签名:就是在摘要的基础上再加一次密,安装 apk 的时候再对加密后的摘要进行验证,只有验证通过才能继续安装
        - 签名过程:APK数据 ——>(计算摘要) 1000101001 ——>(私钥加密:签名) 01001001 ——>(写入签名) 带签名的 APK 数据
        - 验证过程:加密后的 APK数据 ┬——> APK 数据            ——>(摘要算法计算摘要) 1000101001    ┬——> 摘要与公钥解密结果一致,允许安装
                       └——> 签名数据 01001001 ——>(公钥解密签名) 1000101001        ┘
        - 风险点:如果公钥和私钥均被篡改,则接收方是有可能通过这个被篡改的包体的比如
            ├─ 正常:
            │    ├─ 包体 AAA 的摘要为 A,签名为 -A,接收方通过公钥 + 解密得到摘要为 A,计算包体内容得到摘要也为 A,允许安装
            │    └─ 包体 AAA 被改成 BBB,没有私钥,无法生成签名,沿用 -A,接收方通过公钥得到摘要 A,与包体摘要 B,不符不允许安装
            └─ 签名、公钥同时被篡改:
                └─ 包体 AAA 被改成 BBB,篡改放自己的私钥 -1 加密得摘要 -1B,同时篡改公钥为 +1,接收方通过篡改后的公钥 +1 得到摘要 B,与包体摘要一致,允许安装
                
- 数字证书:由签名验证过程可知,APK 包体接收方需要知道公钥和使用的摘要算法才能够进行验证,而数字证书就是用来保证这些信息的可靠性的
    - 证书颁发机构:身份认证机构(Certificate Authority),简称 CA
    - 包含的信息:
        ├─ 证书颁发机构
        ├─ 证书颁发机构签名
        ├─ 证书绑定的服务器域名
        ├─ 证书版本、有效期
        ├─ 签名使用的加密算法(非对称算法,如 RSA)
        └─ 公钥 等
    - 正式的签名 APP 的流程中,签名和摘要算法放到证书里面(放包体里面容易被破解),在安装 APK 的时候则从证书里面获取到摘要算法以及签名
    - 正式安装的时候,会先校验证书的合法性,再校验签名,证书即保证:公钥和签名均没有被篡改,应该完全信任
    
2. 加解密过程:
- 未加密消息流: 
        ├─ 正常:A ——>(传递消息:XXX) B 收到消息 XXX
        └─ 有第三方:    A ——>(传递消息:XXX) C 拦截到消息 XXX,并修改为 CCC ——>(传递消息:CCC) B 收到消息 CCC
- 对称加密:
        ├─ 正常:A ——>(传递消息:+XXX) C 拦截到消息 +XXX 但是没有密钥 +,无法解密 ——>(传递消息:+XXX) B 收到消息 +XXX,用密钥 + 解密得到 XXX
        └─ 密钥被获知:A ——>(传递消息:+XXX) C 拦截到消息 +XXX,用密钥 + 解密得到 XXX,修改为 CCC 并加密 ——>(传递消息:+CCC) B 收到消息 +CCC,用密钥 + 解密得到 CCC
- 非对称加密:
    ├─ 正常:
    │    ├─ A ——>(传递消息:+XXX) C 拦截到消息 +XXX 但是没有私钥 -,无法解密 ——>(传递消息:+XXX) B 收到消息 +XXX,用密钥 - 解密得到 XXX
    │    └─ B ——>(传递消息:-YYY) C 拦截到消息 -YYY 但是没有公钥 +,无法解密 ——>(传递消息:-YYY) B 收到消息 -YYY,用密钥 + 解密得到 YYY
    └─ 拦截到公钥(私钥一般不会被透露,情况基本一致)
        ├─ A ——>(传递消息:+XXX) C 拦截到消息 +XXX 但是没有私钥 -,无法解密 ——>(传递消息:+XXX) B 收到消息 +XXX,用密钥 - 解密得到 XXX
        └─ B ——>(传递消息:-YYY) C 拦截到消息 -YYY 用公钥 + 解密得到 XXX,但是没有私钥无法加密 ——>(传递消息:-YYY) B 收到消息 -YYY,用密钥 + 解密得到 YYY
        
    特点:非对称算法虽然安全,但是在 http 通讯中,服务器用私钥加密的报文所有客户端都能用公钥解密查看内容,虽然不至于被修改但是任然不安全
- HTTPS 加密方案:
    └─ 正常:
        ├─ A ——>(传递消息:*1XXX+*1) C拦截到消息,没有公钥 *1,无法解密 ——>(传递消息:*1XXX+*1) B 收到消息 *1XXX+*1,用密钥 - 解密 +*1 得到随机密钥 *1,用密钥 *1 再解密得 XXX
        └─ B ——>(传递消息:*1YYY) C拦截到消息,没有密钥 *1,无法解密 ——>(传递消息:*1XXX) A 收到消息 *1XXX,用密钥 *1 解密得到 YYY
    描述:HTTPS 的方案是客户端随机生成密钥(*1),用公钥加密得到的密钥 +*1,再用 *1 加密消息后连带 +*1 传递给服务端,服务端先用私钥解密 +*1 得到加密用的密钥,再用密钥去解密消息
    特点:这样的方式,拦截方必须每次消息传递都知道客户端的这个随机密钥(因为每次密钥都是随机的),而要得到这个密钥又只能通过服务器的私钥,要实现这两个条件十分困难,所以此流程比较安全

3. JAR 签名(老机制)及 V2 签名(新机制)

猜你喜欢

转载自blog.csdn.net/qq_37421018/article/details/120698598