浅谈iOS中经常使用加密算法的使用

 之前若是咱们忘记了登陆密码,一般能够经过“找回密码”这样的方式拿回密码,那说明你的隐私数据在他们的数据库中是明文保存的,如今请切记:若是哪一个平台还有这样的方式请马上立刻注销你的帐号,并避免在任何其余平台使用这个平台使用过的密码。请坚信:在网络世界中,只要是明文存在或可逆的东西,都是不安全的。没有哪家公司会告诉你他们的数据库被拖库过,你更没法想象如今的黑色产业早已让你毫无隐私。ios

 千万别一个密码走天下,必定要按期改密码!git

 道高一尺魔高一丈,对用户隐私及一些敏感数据的保护愈来愈重要,在iOS中,苹果封装了Security.framework、CommonCrypto.framework这两个保护信息安全的库,为咱们提供了安全相关的通用API:

  • RSA:公私钥的生成、公钥加密、私钥解密、私钥签名、公钥验签功能,证书信息的读取,以及密钥在KeyChain中存储,查找,删除等功能
  • 哈希:SHA一、SHA22四、SHA25六、SHA38四、SHA512 MD二、MD四、MD5
  • 对称加密:DES、3DES、AES

 这一篇文章,咱们就以“用户输入密码,登陆,服务端验证用户信息,用户上传隐私数据”这个常见场景为例,分享一些密码学常识和加密时经常使用的防破解技巧,至于上述算法相关API的使用,文末我会附上iOS中全部经常使用加密API使用的demo,这里就不浪费篇幅贴代码了。先说两个保护用户隐私的原则:github

  • 网络上不容许明文传递用户隐私信息
  • 本地不容许明文保存用户隐私信息

 再了解下几种算法的特色:算法

对称加密

  • 加密解密共用一个密钥
  • DES 数据加密标准,安全强度不够已经不多用了
  • 3DES 使用三个密钥对相同的数据执行三次加密 强度略高,但密钥的保护一直是个隐患因此也不经常使用
  • AES 高级密码标准 用得最多
  • 两种经常使用加密模式:
    • ECB:
       最基本的加密方式,无初始向量,相同的明文永远生成不变的密文,容易受到密码本重放攻击,不多用
    • CBC:
       明文被加密前要与前面的密文进行异或运算后再加密,所以只要选择不一样的初始向量,相同的密文加密后会造成不一样的密文,这是目前应用最普遍的模式。CBC加密后的密文是上下文相关的,但明文的错误不会传递到后续分组,但若是一个分组丢失,后面的分组将所有做废(同步错误)。
       能够有效的保证密文的完整性,若是一个数据块在传递是丢失或改变,后面的数据将没法正常解密。

RSA

关于RSA相关知识请参考:
非对称加密--RSA原理浅析
RSA的主场-证书签名之OpenSSL演示数据库

这里再也不赘述。macos

哈希算法

也就是常说的散列函数,严格意义上它并非一种加密算法,但它经常与加密算法一块儿出现,做为一种组合方式。哈希具备如下特色:编程

  • 算法是公开的
  • 对相同的数据运算,获得的结果是同样的
  • 同一算法对不一样的数据运算,获得的结果长度是固定的,如MD5的结果必定是128bit,32个字符(16进制表示),因此散列碰撞是必然的偶然
  • 不可逆,可是能够经过彩虹表反查询
  • 一般做为信息“指纹”--信息摘要,用来作数据识别(版权、搜索引擎、数字签名等)。

实际应用

 知道了每种算法的特色,回到应用场景:用户输完密码点击登陆时,咱们如何保证用户信息是足够安全的呢?安全

  • 对称加密:密钥传输有隐患,且在客户端加密前和服务端解密后会出现明文,不安全。
  • RSA:安全性高,网络劫持很难破解,可是服务端拿到客户端加密后的密文怎么办呢?用私钥解密,解密以后拿到明文信息?大忌,没有哪一个服务端是安全的,更无法保证数据库人员的我的泄露用户信息。不可取。
  • 哈希:
    • 直接MD5?用户输入常规组合几率很大,暴力破解风险很高,不可取。本地加盐,很变态的盐?安全性有必定保障,缺点是盐写死在程序里了,写代码的人也有泄露的可能性,一旦泄漏结果是毁灭性的,不可取。
    • HMAC:Keyed-Hashing for Message Authentication,这是一种使用单向散列函数来构造消息认证码的方案,而不是算法。
        在第一次注册时,服务端下发一个随机密钥 n,这个密钥会在客户端和服务端都保存一份(支持服务端更新),客户端的 n 用做之后每次登陆时的“盐”参与第一次散列运算,并将第一次散列运算的结果 s 发给服务端做为用户密码信息保存到数据库中,这样用户的真实密码不管是客户端仍是服务端都不知道,也不存在数据库被拖库泄露的问题。服务端保存的 n 用于当用户换设备登陆或卸载从新装时验证经过后再次将 n 下发给客户端保存。
       用户每次登陆时,服务器会再动态下发一个随机值做为密钥,并在会话中记下这个随机值 r,客户端先用本地保存的 n 对用户密码作散列运算获得 s ,再用 r 对 s 作一次MAC(Message Authentication Codes)运算并将运算结果发送给服务端,服务端也从数据库中取出用户的密码散列值作一样的运算,并将结果与客户端进行对比。为了防止网络中间人攻击,还需将时间戳(服务器时间,通常精确到分钟)参与校验,黑客就很难破解了。这是目前最主流的安全方案。

 如今用户登陆成功,如今要上传一份敏感数据,咱们如何保证数据的完整性呢?结合上面的分析,推荐AES的CBC加密方式,安全性高,还能保证完整性,数字签名一样也能够验证数据完整性,用RSA对数据的hash值进行加密,服务端接收完数据后,用私钥解密获得hash值,与接收数据的hash值做比对。bash

补充:

iOS中常见加密算法的使用:EncryptDemo
在Demo中,对称加密AES的加密解密函数:服务器

CCCryptorStatus CCCrypt(
    CCOperation op,         /* kCCEncrypt, etc. */
    CCAlgorithm alg,        /* kCCAlgorithmAES128, etc. */
    CCOptions options,      /* kCCOptionPKCS7Padding, etc. */
    const void *key,
    size_t keyLength,
    const void *iv,         /* optional initialization vector */
    const void *dataIn,     /* optional per op and alg */
    size_t dataInLength,
    void *dataOut,          /* data RETURNED here */
    size_t dataOutAvailable,
    size_t *dataOutMoved)
    API_AVAILABLE(macos(10.4), ios(2.0));  
复制代码

调用CCCrypt时,用户敏感数据不要直接做为参数传递,不然逆向很容易hook到,一般的作法是对敏感数据作异或、加盐等处理,具体根据须要本身设计。

iOS app签名机制详解 推荐阅读:
iOS应用签名(上)
iOS应用签名(下)

iOS中对钥匙串的操做推荐:SSKeyChain

实践出真知,咱们下篇再会~

老规矩,有错误请积极指正,有问题请踊跃留言。

更多一手好文更新,请关注个人我的微信公众号:面向将来编程 撒花✧(≖ ◡ ≖✿)

相关文章
相关标签/搜索