密码学

作者: 异想天不开_9950 | 来源:发表于2018-05-09 17:07 被阅读8次
    三大类加密算法 算法特点 代表的算法
    哈希(散列函数)算法 1. 算法公开
    2. 对不同数据加密结果是定长的32位字符
    3. 加密之后的数据是不可逆的
    MD5
    SHA 256/512
    HMAC
    对称加密算法 1. 加密后可逆
    2. 加密和解密使用同一个“密钥”(密钥的保密工作非常重要,密钥一般会定期换,密钥管理非常麻烦)
    3. 加密效率高
    DES
    3DES
    AES
    非对称加密算法 1. 加密后可逆
    2. 公钥和私钥(使用公钥加密,私钥解密;使用私钥加密,公钥解密)
    3. 纯数学运算,加密效率非常低
    RSA
    对称加密算法的两种加密方式 描述
    ECB 电子代码本,就是说每一个数据块都是独立加密的
    CBC 密码块链,使用一个密钥和一个“初始化向量(IV)”对数据执行加密转换,每一个数据块的加密都与上一个数据块有关联
    如果在传输数据的过程中,一个数据块被破坏了,那么整个数据都没法解密了
    加密算法 应用场景
    MD5 1. 一般用来做密码加密
    2. 版权问题(对比文件MD5值 )
    3. 搜索引擎(搜索iOS 密码学 与 密码学 iOS结果是一样的,原因:取MD5值,按位相加)
    4. 百度云&360云盘秒传(对比文件MD5值)
    DES 数据加密标准(用的少,因为强度不够)
    3DES 使用3个密钥,对相同的数据执行3次加密,强度增强(更加用的少)
    AES 高级加密标准,目前美国国家安全局使用的就是AES(用的少,因为强度不够)

    一、数据加密方法

    以前对于用户密码一般使用MD5进行加密,但是现在单独使用MD5对用户密码加密已经不安全了!

    现在的解决方案:

    1. 加盐处理(可以保证MD5不被轻易的破解) — 早期的使用!
    ( 密码 + 盐 ) . md5
    盐:静态字符串。一定要足够复杂,足够长!如:

     static NSString *salt = @“SOFILKSFK92832349472JLF;p]qi3323hoos+_)(*^%’’//?adsofu8 {}SKDFJ@#%*(((&OKDKkdjfdjkdj”;
    

    其实这种方法也不是足够安全,它有一个最大的弊端。盐:是固定写死的。写死在程序里面的。一旦盐泄漏,就不安全了!

    2. HMAC 用一个密钥加密,然后做两次散列!-- 安全的做法!

     pwd = [pwd hmacMD5StringWithKey:@“从服务器获取的key”]; //每一个账号对应着不同的key!
    

    这个key是密钥!这个密钥是从服务器获取的!

    HMAC加密关键点在于key(密钥)。它是怎么产生的,又是什么时候产生的呢?

    注:第一次的第一个密钥来自于用户注册!

    • 1)首先,客户端给服务器发送一个账号。
    • 2)服务器拿到账号后会保存该账号,并对应着账号生成一个Key(密钥),紧接着服务器会把这个密钥返回给客户端。
    • 3)客户端得到Key(密钥)后,会立刻将密钥保存在本地。接着使用 HMAC & Key 对密码进行加密,将加密后的32位字符串再发送给服务器。((密码+key)).HMAC
    • 4)服务器将HMAC之后的密码进行保存。

    以后的每一次登录都需要走第3步对密码(HMAC & Key)加密后发送服务器,服务器对密码进行验证。可以看出来保存在本地的 Key 很关键!如果没有这个 Key 用户是不可能登录成功的!所以可以把 Key 放入钥匙串中,避免应用删除后,本地密钥也被删除!

    image.png

    那如果用户换了新手机该怎么办呢?

    解决方案:

    • 重新根据你的账号发送给服务器,找服务器获取一次Key。
    • 客户端拿到Key(密钥)后,将密钥保存在本地。接着使用 HMAC & Key 对密码进行加密,将加密后的32位字符串再发送给服务器。
    • 服务器对密码进行验证。

    这种加密方式有什么好处呢?
    我们都知道QQ有一个设备锁的功能。它的实现原理就是 HMAC 的实现原理!如果你在之前设置过设备锁,那么服务器不会立刻把 Key(密钥)给你,而是告诉你等待上一个设备进行验证。如果你的上一个设备不允许,那么这个 Key 是永远不会拿到的。

    如果黑客拦截了你的请求,拿到了你的 HMAC 字符串,这样就可以模仿你给服务器发送请求,从而获取你的登录权限。那我们该如何保证用户的安全呢?

    最常用以及最有效的解决方案:

    • 改第3步。客户端将HMAC加密后的密码+年月日时分,然后整体md5加密。再发送给服务器。(((密码+key)).HMAC + “201805071622”).md5
    • 服务器也通过此方法,比如(((密码+key)).HMAC + “201805071623”).md5后,得到的字符串与客户端发送的进行对比。如果对不上,服务器会立即换成上一分钟的时间再次进行对比。(((密码+key)).HMAC + “201805071622”).md5这就是服务器的处理逻辑。
      image.png

    这样可以保证,如果你发送网络请求,中间的延时能够有最少61秒的时间,这样保证了正常的网络请求发送。这样的好处是如果一个黑客拦截了你的网络请求,他必须务必在120秒之内对其服务器进行访问。如果没访问,获取的网络请求的字符串就失效了。

    这种方式的特点:

    • 只有分钟没有秒
    • 做到每次加密的结果是不一样的,加密的结果受时间的影响很大

    很多公司都愿意把时间作为加密算法中的一个参数,这样保证了每一次加密结果都是不一样的。而且保证了可以和服务器做一个合适的验证。

    二、数字签名原理

    我们发送数据的时候,要保证数据在发送的过程中不能被篡改。所以就要求我们在发送数据的时候,对数据数字签名。


    image.png

    三、破解对称加密算法的思路

    iOS系统库中定义了软件开发中常用的加解密算法,接口为C语言形式。具体包括了以下几个大类:

    #include <CommonCrypto/CommonCryptor.h>  //常用加解密算法
    #include <CommonCrypto/CommonDigest.h>   //摘要算法
    #include <CommonCrypto/CommonHMAC.h>
    #include <CommonCrypto/CommonKeyDerivation.h>
    #include <CommonCrypto/CommonSymmetricKeywrap.h>
    

    其中第一类常用加解密算法包含了AES、DES和已经废弃的RC4。第二类摘要算法包括如MD5、SHA等。

    CCCrypt(<#CCOperation op#>, <#CCAlgorithm alg#>, <#CCOptions options#>, <#const void *key#>, <#size_t keyLength#>, <#const void *iv#>, <#const void *dataIn#>, <#size_t dataInLength#>, <#void *dataOut#>, <#size_t dataOutAvailable#>, <#size_t *dataOutMoved#>);
    CC_MD5(<#const void *data#>, <#CC_LONG len#>, <#unsigned char *md#>);
    CC_SHA256(<#const void *data#>, <#CC_LONG len#>, <#unsigned char *md#>):
    

    像上面这些公开加密算法的函数,都是系统的函数。既然是系统的函数,那么 fishhook 就能够 HOOK 住。

    调用系统加密函数

    1. 以前的做法

    一般像 RSA 公钥,这种非常重要核心的数据,你一般会采取什么方式保存在本地呢?很多人可能会使用钥匙串访问,因为钥匙串访问在本地,所以会感觉很安全。

    但是,钥匙串访问也是调用的方法,一样传递的参数。与对称加密算法 CCCrypt 一样,钥匙串访问也是调用的系统函数,所以我们一样可以 HOOK。

    假如:我们有一个 RSA 公钥,一个明文A。当我们调用 CCCrypt() 函数的时候,我们会把明文A参数传进去,然后进行加密,生成一个密文B。对于一个黑客来说,他没必要对密文B进行破解。他只需要 HOOK CCCrypt() 函数,拿到明文A。所以,我们要注意,在调用系统加密函数的时候,不要直接把核心数据丢进去。

    2. 今后的做法

    采取封装的形式!

    1. 自定义一个函数,把明文A异或盐(从服务器请求或本地存储的都行,一个账号一个盐),得到密文B
    2. 把密文B丢给系统的加密算法,等到密文C
    3. 把密文C传给服务器

    注:第1步中可以函数中再调函数,一层层加密。这样就加大了黑客解密的难度。

    解密过程

    解密:

    1. 密文C调用系统的解密算法,得到密文B
    2. 密文B同样异或盐,得到明文A

    黑客也很难得到你的明文

    作为黑客,由于他不知道你的逻辑,所以他想得到你的明文A是比较困难的。

    1. 首先,他会去 HOOK 系统的加密算法的函数,一个函数一个函数去 HOOK。
    2. 当他 HOOK 到之后,发现你调用了加密算法的函数,他会去看函数的返回值,对比这个函数的返回值(密文C)是不是你发给服务器的核心数据。
    3. 当他发现两者一样的时候,他就会去解密(密文C)。当他解密成功以为会拿到明文A,其实只是拿到了密文B,接下来他还需要把密文B解密。而这个过程,对我来说,我知道逻辑很好做,但是对于黑客来说,他只能去猜。是不是 HOOK 出了问题?是不是 HOOK 的方法出了问题?他就会这样一直怀疑,这样他想真正通过分析找到封装的函数的机率就非常低了。

    相关文章

      网友评论

        本文标题:密码学

        本文链接:https://www.haomeiwen.com/subject/gaomrftx.html