《iOS底层原理文章汇总》
1.通过私钥生成.csr文件
openssl req -new -key private.pem -out rsacert.csr
要用.csr到专门颁发证书的机构去签名,签名证书是合法的,也能自己进行签名,但是自签的签名是没有被认证的
openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt
收到一个crt的证书,此证书的作用是比如做https服务器,需要将这个证书放到公司的服务器上,让请求方去接收
.crt证书转成能使用的der证书,从苹果拿到的是der证书,会在本地钥匙串中对它绑定一个密钥,即p12,der证书里面的p12
openssl x509 -outform der -in rsacert.crt -out rsacert.der
![](http://img.e-com-net.com/image/info10/69437d93cac743979365242ae794cb70.jpg)
获取p12文件,p12和der是一对,两个文件可以在代码里面做加解密,iOS中通过der和p12这两个文件进行加解密,代码里面只能用der证书,加密完后的文件格式是二进制data
base64编码message.txt为abc.txt,Base64编码由0-9,a-z,A-Z,+/=65个字母组成,如果要编码的字节数不能被3整除,最后会多出1或2个字节,则先使用0字节值在末尾补足,使其能够被3整除,然后再进行Base64的编码。在编码后的Base64文本后加上一个或两个=号,代表补足的字节数。也就是说,当最后剩余两个八位(待补足)字节(2个byte)时,最后一个6位的Base64字节块有四位是0值,最后附加上两个等号;如果最后剩余一个八位(待补足)字节(1个byte)时,最后一个6位的base字节块有两位是0值,最后附加一个等号。
编码:base64 message.txt -o abc.txt
解码:base64 abc.txt -o 123.txt -D
Base64只适用于表示二进制文件,Base64编码后文件会大1/3,不适用于大型的数据编码
RSA对代码进行加密,加密后是二进制文件,用Base64打印排查错误,查看能不能加密成功
2.RSA加密
两次的加密结果不一样,是因为RSA内部的填充模式
kSecPaddingNone 不填充,密文每次都不会变化
通过RSA和服务端通讯,公钥放客户端,私钥放服务端
对称加密(KEY)定期来一次变化,服务端通过私钥给KEY加密,传送到客户端,客户端通过公钥解密,之后通过KEY对称加密进行通讯
客户端中存在公钥,一旦发现公钥泄露,可以换公钥,所有APP统一换,私钥在网络上不传递,只在公司服务器上有
RSA最常见的使用场景是做签名
3.HASH
HASH:MD5,SHA1,SHA256,SHA512
对称加密:DES,3DES,AES
Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数
- 算法是公开的
- 对相同数据运算,得到的结果是一样的
- 对不同数据运算,如MD5得到的结果默认是128位,32个字符(16进制标识)。
- 这玩意没法逆运算
- 信息摘要,信息“指纹”,是用来做数据识别的。
I.数据(无限大或长) HASH运算 结果为16^32(有限长) 必然会有两个或多个不同的数据,拥有同样的HASH值,这就是散列碰撞
II.HASH用途
- 用户密码的加密
- 搜索引擎
- 版权
- 数字签名
III.用户密码加密
服务端不能保存用户的明文密码,开发者都不知道用户的真实密码最安全
网络传输数据(隐私数据),不能明文,本地保存数据(隐私数据),不能明文。
对密码进行处理
A.密码直接进行md5,但有专门反md5的网站https://www.cmd5.com/,不安全
B.给密码加盐,但盐已经泄露给开发者,也有泄露风险
C.HMAC:KEY由服务器提供,一个账号一个KEY
用户注册是去服务端查询,此账号是否有KEY绑定,若没有即首次,分配一个key,此时可通过RSA加密的方式分配KEY,若是同一个账号换一台新手机,先去服务端请求KEY,表现形式是向用户的设备上请求用户授权,最典型的例子是苹果AppID登录新设备时,会让在已经登录过的设备上进行授权,既能方便获取HMAC加密的key,也能让用户感知到登录的安全,可以通过保存手机设备的MAC的地址来判断是否要返回KEY到客户端
本地保存KEY,最好用钥匙串keychain访问,不要自己放沙盒,钥匙串访问本身进行加密了,可以保存明文或密文,钥匙串访问存进去是加密的,取出来是解密的
盐在App中不好更新,而HMAC中的KEY,可以随时通过服务端更新,比如,用户输入正确密码后,即用的老的KEY登录了,服务端返回新的KEY可以将老的KEY替换掉,所有的设备都能替换掉,KEY只针对绑定KEY的用户
此时,用户的密码是安全了,但是仍旧可以拦截KEY加密后的HASH值,进行模拟登录,怎样避免呢?
D:HMAC+时间戳
客户端用密码的HMAC哈希值+当前时间到分钟进行md5加密后请求服务端,服务端接收到请求后,用服务端的当前时间比客户端的时间晚一分钟+HMAC哈希值进行md5加密后进行匹配,若无法匹配,服务端将时间往前推一分钟再次进行匹配,黑客若想拦截登录此密码必须在1分59秒之内完成,否则无法进行模拟登录
一分两分钟的时间戳由自己决定,每次加密的结果不一样,受时间的影响特别大,使用的时间戳为服务器返回的时间戳,每次请求都返回时间戳,不会使用手机本地时间
4.HASH其他用途
I.搜索
搜索关键字:iOS 深圳 cloud
会将这三个字符串的HASH值相加,三个128个二进制位相加,本身是一串数字,展现出来是16进制表现形式为字符串
iOS:1bdf605991920db11cbdf8508204c4eb
深圳:7a399889b9a4aed64afd0cf95941b975
cloud:a1234b3161b4fbfdfb96dd576b65bbea
会将三个相加得到的结果是一个数字,在词库中搜索这个数字,则搜到的结果和排列组合无关,因为相加的结果始终相同
II.版权
文件上传到网站,会保存HASH数据。图片、视频,看到的和原始文件是不一样的,肉眼看不出来,对比知道哪个是正版哪个是盗版
网盘做数据识别用哈希值
helloworld.txt更改文件名葫芦兄弟.mp3后,哈希值并没有改变,敏感文件会被删掉,改名字没有用,哈希值没有变化
若希望哈希值发生变化,可以通过Base64转化,但此时文件会变大
若希望哈希值发生变化,文件变小,可以转化为zip文件
二进制文件的本质发生变化,哈希值才会发生变化
网盘中去识别数据,根据哈希值来识别
代码函数中提供终端命令,方便试算
#pragma mark - 散列函数
/**
* 计算MD5散列结果
*
* 终端测试命令:
* @code
* md5 -s "string"
* @endcode
*
* 提示:随着 MD5 碰撞生成器的出现,MD5 算法不应被用于任何软件完整性检查或代码签名的用途。
*
* @return 32个字符的MD5散列字符串
*/
- (NSString *)md5String;
/**
* 计算SHA1散列结果
*
* 终端测试命令:
* @code
* echo -n "string" | openssl sha -sha1
* @endcode
*
* @return 40个字符的SHA1散列字符串
*/
- (NSString *)sha1String;
/**
* 计算SHA256散列结果
*
* 终端测试命令:
* @code
* echo -n "string" | openssl sha -sha256
* @endcode
*
* @return 64个字符的SHA256散列字符串
*/
- (NSString *)sha256String;
/**
* 计算SHA 512散列结果
*
* 终端测试命令:
* @code
* echo -n "string" | openssl sha -sha512
* @endcode
*
* @return 128个字符的SHA 512散列字符串
*/
- (NSString *)sha512String;
#pragma mark - HMAC 散列函数
/**
* 计算HMAC MD5散列结果
*
* 终端测试命令:
* @code
* echo -n "string" | openssl dgst -md5 -hmac "key"
* @endcode
*
* @return 32个字符的HMAC MD5散列字符串
*/
- (NSString *)hmacMD5StringWithKey:(NSString *)key;
/**
* 计算HMAC SHA1散列结果
*
* 终端测试命令:
* @code
* echo -n "string" | openssl sha -sha1 -hmac "key"
* @endcode
*
* @return 40个字符的HMAC SHA1散列字符串
*/
- (NSString *)hmacSHA1StringWithKey:(NSString *)key;
/**
* 计算HMAC SHA256散列结果
*
* 终端测试命令:
* @code
* echo -n "string" | openssl sha -sha256 -hmac "key"
* @endcode
*
* @return 64个字符的HMAC SHA256散列字符串
*/
- (NSString *)hmacSHA256StringWithKey:(NSString *)key;
/**
* 计算HMAC SHA512散列结果
*
* 终端测试命令:
* @code
* echo -n "string" | openssl sha -sha512 -hmac "key"
* @endcode
*
* @return 128个字符的HMAC SHA512散列字符串
*/
- (NSString *)hmacSHA512StringWithKey:(NSString *)key;
#pragma mark - 文件散列函数
/**
* 计算文件的MD5散列结果
*
* 终端测试命令:
* @code
* md5 file.dat
* @endcode
*
* @return 32个字符的MD5散列字符串
*/
- (NSString *)fileMD5Hash;
/**
* 计算文件的SHA1散列结果
*
* 终端测试命令:
* @code
* openssl sha -sha1 file.dat
* @endcode
*
* @return 40个字符的SHA1散列字符串
*/
- (NSString *)fileSHA1Hash;
/**
* 计算文件的SHA256散列结果
*
* 终端测试命令:
* @code
* openssl sha -sha256 file.dat
* @endcode
*
* @return 64个字符的SHA256散列字符串
*/
- (NSString *)fileSHA256Hash;
/**
* 计算文件的SHA512散列结果
*
* 终端测试命令:
* @code
* openssl sha -sha512 file.dat
* @endcode
*
* @return 128个字符的SHA512散列字符串
*/
- (NSString *)fileSHA512Hash;
5.数字签名
数字签名目的:验证这段二进制数据是否是原始机构颁发的
服务端传输数据的时候,传送二进制数据和二进制数据的哈希值
客户端收到数据的时候,计算二进制数据的哈希值和服务端返回的二进制哈希值是否匹配,若不匹配,则说明数据被篡改过,丢弃不用,此时,若二进制数据被篡改,二进制数据的哈希值也被篡改,则无法识别,需要将二进制数据的哈希值,128位属于小数据,用RSA进行加密传送到客户端,客户端解密后和计算的二进制数据哈希值进行对比,防止数据被篡改
RSA加密二进制数据哈希值的这一段数据成为数字签名
数字签名应用非常广泛,支付宝,银行,支付平台都是用数字签名,iOS也使用代码签名
要想篡改,只能拿到服务端的私钥,而私钥基本上拿不到的