内容简介:以前如果我们忘记了登录密码,通常可以通过“找回密码”这样的方式拿回密码,那说明你的隐私数据在他们的数据库中是明文保存的,现在请切记:如果哪个平台还有这样的方式请立刻马上注销你的账号,并避免在任何其他平台使用这个平台使用过的密码。请坚信:在网络世界中,只要是明文存在或可逆的东西,都是不安全的。没有哪家公司会告诉你他们的数据库被拖库过,你更无法想象现在的黑色产业早已让你毫无隐私。千万别一个密码走天下,一定要定期改密码!道高一尺魔高一丈,对用户隐私及一些敏感数据的保护越来越重要,在iOS中,苹果封装了Securi
以前如果我们忘记了登录密码,通常可以通过“找回密码”这样的方式拿回密码,那说明你的隐私数据在他们的数据库中是明文保存的,现在请切记:如果哪个平台还有这样的方式请立刻马上注销你的账号,并避免在任何其他平台使用这个平台使用过的密码。请坚信:在网络世界中,只要是明文存在或可逆的东西,都是不安全的。没有哪家公司会告诉你他们的数据库被拖库过,你更无法想象现在的黑色产业早已让你毫无隐私。
千万别一个密码走天下,一定要定期改密码!
道高一尺魔高一丈,对用户隐私及一些敏感数据的保护越来越重要,在iOS中,苹果封装了Security.framework、CommonCrypto.framework这两个保护信息安全的库,为我们提供了安全相关的通用API:
- RSA:公私钥的生成、公钥加密、私钥解密、私钥签名、公钥验签功能,证书信息的读取,以及密钥在KeyChain中存储,查找,删除等功能
- 哈希:SHA1、SHA224、SHA256、SHA384、SHA512 MD2、MD4、MD5
- 对称加密:DES、3DES、AES
这一篇文章,我们就以“用户输入密码,登录,服务端验证用户信息,用户上传隐私数据”这个常见场景为例,分享一些密码学常识和加密时常用的防破解技巧,至于上述算法相关API的使用,文末我会附上iOS中所有常用加密API使用的demo,这里就不浪费篇幅贴代码了。先说两个保护用户隐私的原则:
- 网络上不允许明文传递用户隐私信息
- 本地不允许明文保存用户隐私信息
再了解下几种算法的特点:
对称加密
- 加密解密共用一个密钥
- DES 数据加密标准,安全强度不够已经很少用了
- 3DES 使用三个密钥对相同的数据执行三次加密 强度略高,但密钥的保护一直是个隐患所以也不常用
- AES 高级密码标准 用得最多
- 两种常用加密模式:
- ECB:
最基本的加密方式,无初始向量,相同的明文永远生成不变的密文,容易受到密码本重放攻击,很少用 - CBC:
明文被加密前要与前面的密文进行异或运算后再加密,因此只要选择不同的初始向量,相同的密文加密后会形成不同的密文,这是目前应用最广泛的模式。CBC加密后的密文是上下文相关的,但明文的错误不会传递到后续分组,但如果一个分组丢失,后面的分组将全部作废(同步错误)。
可以有效的保证密文的完整性,如果一个数据块在传递是丢失或改变,后面的数据将无法正常解密。
- ECB:
RSA
这里不再赘述。
哈希算法
也就是常说的散列函数,严格意义上它并不是一种加密算法,但它常常与加密算法一起出现,作为一种组合方式。哈希具有以下特点:
- 算法是公开的
- 对相同的数据运算,得到的结果是一样的,所以散列碰撞是必然的
- 同一算法对不同的结果运算,得到的结果长度是固定的,如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值作比对。
补充:
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中对钥匙串的操作推荐: SSKeyChain
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。