在我们的研发过程中,或多或少都会涉及到加密的工作。
密码学最开始是用于军事领域。起源于凯撒大帝的密码本,并一直持续到上世纪70年代,也就是二战期间。
在上世纪70年代出现了新的算法RSA(三个人的名字),RSA的加密算法是公开的!
秘钥加密,公钥解密!公钥加密,私钥解密!他可用因式分解破解,但是需要用时50年。有一本书《我和RSA的20年》有具体描述。
有RAS衍生出的算法有:
1.哈希(散列)函数: MD5, SHA1, SHA256/512
2.对称加密算法:DES, 3DES, AES(这个是美国国家安全局使用的,苹果的钥匙串访问也是使用的这个。他也叫做高级密码标准)
3.非对称加密算法
以上都是算法公开的。
散列函数:
对相同的数据进行加密,得到的结果是一样的。
对不同的数据加密,得到的结果是定长的。
是不可逆的,也就是说密码加密后,不能得到明文密码了。
上面是加密的算法,那么在还需要一种加密的方式:
ECB: 电子密码本,将一个数据拆分多块,然后独立加密,最后拼接
CBC: 密码块链,将一个数据拆分多块,使用一个秘钥和一个“向量”对数据赤星加密抓换,能保证密文的完整性,如果一个数据发生变化,后面的所有数据都将会被破坏。
下面来说说,我们在iOS开发中会用到的加密方式:
MD5:在早起我们使用的比较多,但是因为强度不够,现在用的比较少了。中间有过一段时间是利用加盐来增加强度。但是还是不够,并且不方便使用。
MHAC:近一两年,在国内开始使用增多(给定一个秘钥,对明文进行拼接,在进行两次散列)
这个秘钥最好是有服务器返回,在注册的时候就给定,成功后,前端可以保存在钥匙串中,因为钥匙串是ASE加密,所以也是很安全的。
那么这里会出现一个问题:如果用户换了设备,该怎么办呢?!先从本地根据账户取秘钥,如果秘钥不存在就去服务器取秘钥(这里可以干很多事情哦)。如果秘钥存在,可登录。
那么去服务器取秘钥时,可以干什么事情呢?!就如微信,支付宝,QQ,他们切换账号登录时,会有一个登录授权:
由原设备授权或手机验证码授权。授权以后,服务器才会返回秘钥。这时把秘钥保存在当前设备中即可。
思路是这样,具体实现就看产品如何设计了。MD5,MHAC都是哈希(散列)函数,不可逆,那么多用于验证,如登录。
在重要信息传输的时候,不要使用哈希(散列)函数,因为不可逆,所以,传输后不能解密就完全无用了。
对称加密:
上面说到的AES和DES都只是加密的算法,ECB和CBC是加密的方式,上面有提到过。
那么在iOS开发中如何使用这个呢?!其实就只需要用到一个函数:
导入头文件:#import <CommonCrypto/CommonCrypto.h>
CCCryptorStatus *status = 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#>)
关于这里的参数需要说明下:
CCOperation 一个枚举,是加密还是解密
CCAlgorithm 加密的算法,也是一个枚举,使用的是AES还是DES或者其他,具体的可以在xCode中去查看。
CCOptions 加密的方式,是使用的ECB还是使用的CBC。
void *key 显而易见,加密秘钥(注意,这里是16进制的)
keyLength 秘钥的长度
void *iv 向量,如果是EBC则不需要制定
void *dataIn 需要加密的数据
dataInLength 需要加密数据的长度
dataOut 密文的内存地址
dataOutAvailable 密文缓冲区的大小
dataOutMoved 密文的实际大小
使用这个函数就可以进行加密。然后在用status判断是否等于kCCSuccess,如果是则加密成功。
然后用[NSData dataWithBytes:<#(nullable const void *)#> length:<#(NSUInteger)#>]转成base64就OK了。
RSA:(很多数学运算,效率非常低),多用于数字签名,保证数据安全且不会被修改。
iOS开发中无法直接使用PEM格式的证书,真正使用的是DER格式,也就是二进制格式。所以,需要转码。
数字签名:
客服端:数据 (哈希函数加密)--------> 密文 (RSA公钥加密)------> 数字签名 最后把数字签名和数据一起传给服务端
服务端: 数字签名(私钥RSA解密) --------> 32位密文 == 32位密文 <--------- (哈希函数加密)数据
上面这个就是数字签名及交互的理解图。