iOS风控专题

iOS数据安全—加密解密「学习总结」

2018-08-24  本文已影响22人  饭饭男

转载 https://blog.csdn.net/qq_30513483/article/details/60143441

写在前面
在写项目中,数据的安全性至关重要,而仅仅用 POST 请求提交用户的隐私数据,还是不能完全解决安全问题。因此:我们经常会用到加密技术,比如说在登录的时候,我们会先把密码用MD5加密再传输给服务器 或者 直接对所有的参数进行加密再POST到服务器。
记得最初接触加密,也不懂,就根据文档,用的是 md5,直接调一方法就OK 了(感觉加密也简单的)-->淡淡的一笑!

相信很多开发者跟我当初一样,只是根据项目经理或者文档指示进行加密,简单会使用 但并不知道加密知识体系和内在原理,于是整理了一份相关资料。时间有限,知识并未全覆盖,有遗漏或者错误,忘指正。

image

目录:

  1. 数据安全介绍
  2. 常用加密算法
  3. 常用加密方式
  4. Base64编码方案
  5. 加密实现代码
    5.1 MD5加密算法
    5.2 对称加密算法AES和DES
    5.3 非对称加密RSA
  6. HTTPS基本使用
  7. 数据安全–加密解密效果
  8. 加密实战应用场景(持续更新)
1.数据安全介绍
2.常用加密算法
常用加密算法 名称
编码方案 Base64
哈希(散列)函数 MD5(消息摘要算法)
SHA1
SHA256
对称加密算法 DES
AES
非对称加密算法 RSA
HTTPS HTTP+SSL协议
3.常用加密方式
常用加密方式
1.通过简单 BASE64编码 防止数据明文传输
2.对普通请求、返回数据,生成MD5校验(MD5中加入动态密钥),进行数据完整性(简单防篡改,安全性较低,优点:快速)校验
3.对于重要数据,使用RSA进行数字签名,起到防篡改作
4.对于比较敏感的数据,如用户信息(登陆、注册等),客户端发送使用RSA加密,服务器返回使用DES(AES)加密
5.要想非常安全的传输数据,建议使用https。抓包不可以,但是中间人攻击则有可能。建议双向验证防止中间人攻击
4.Base64编码方案
  1. Base64简单说明
    描述:Base64可以成为密码学的基石,非常重要。
    特点:可以将任意的二进制数据进行Base64编码
    结果:所有的数据都能被编码为并只用65个字符(A~Z a~z 0~9 + / =)就能表示的文本文件。
    注意:对文件进行base64编码后文件数据的变化:编码后的数据~=编码前数据的4/3,会大1/3左右。

  2. Base64编码原理和处理过程

Base64编码原理
1、将所有字符转化为ASCII码
2、将ASCII码转化为8位二进制
3、将二进制3个归成一组(不足3个在后边补0)共24位,再拆分成4组,每组6位
4、统一在6位二进制前补两个0凑足8位
5、将补0后的二进制转为十进制
6、从Base64编码表获取十进制对应的Base64编码
Base64处理过程
1、转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。
2、数据不足3byte的话,于缓冲区中剩下的bit用0补足。然后,每次取出6个bit,按照其值选择查表选择对应的字符作为编码后的输出。
3、不断进行,直到全部输入数据转换完成。
4、如果最后剩下两个输入数据,在编码结果后加1个“=”;
5、如果最后剩下一个输入数据,编码结果后加2个“=”;
6、如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。

在这里提供几张图结合上面的处理过程,好理解。

image
  1. Base64实现代码

简单方法直接拿走,调用

// 对一个字符串进行base64编码,并且返回-(NSString *)base64EncodeString:(NSString *)string {    // 1.先转换为二进制数据    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];    // 2.对二进制数据进行base64编码,完成之后返回字符串    return [data base64EncodedStringWithOptions:0];} // 对base64编码之后的字符串解码,并且返回-(NSString *)base64DecodeString:(NSString *)string {    // 注意:该字符串是base64编码后的字符串    // 1.转换为二进制数据(完成了解码的过程)    NSData *data = [[NSData alloc]initWithBase64EncodedString:string options:0];     // 2.把二进制数据在转换为字符串    return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];} //---------------------------<#我是分割线#>------------------------------// NSLog(@"%@",[self base64EncodeString:@"A"]);NSLog(@"%@",[self base64DecodeString:@"QQ=="]);

PS.终端执行编码和解码

如:编码:base64 123.png -o 123.txt解码:base64 123.txt -o test.png -D
4.加密实现代码

哈希(散列)函数
特点:

用途:

MD5消息摘要算法

提升MD5加密安全性,解决办法

消息认证机制(HMAC)简单说明

简单示例

#pragma mark - md5加密方法- (NSString *)md5String {    const char *str = self.UTF8String;    uint8_t buffer[CC_MD5_DIGEST_LENGTH];    CC_MD5(str, (CC_LONG)strlen(str), buffer);    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];} #pragma mark - HMACMD5加密方法- (NSString *)hmacMD5StringWithKey:(NSString *)key {    const char *keyData = key.UTF8String;    const char *strData = self.UTF8String;    uint8_t buffer[CC_MD5_DIGEST_LENGTH];    CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer);    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];} /** *  返回二进制 Bytes 流的字符串表示形式 *  @param bytes  二进制 Bytes 数组 *  @param length 数组长度 *  @return 字符串表示形式 */- (NSString *)stringFromBytes:(uint8_t *)bytes length:(int)length {    NSMutableString *strM = [NSMutableString string];    for (int i = 0; i < length; i++) {        [strM appendFormat:@"%02x", bytes[i]];    }    return [strM copy];} //---------------------------<#我是分割线#>------------------------------// // md5加密调用NSLog(@"%@",[@"520it" md5String]); // (明文+加盐)MD5加密调用NSLog(@"%@",[[@"520it" stringByAppendingString:salt] md5String]); // hmacMD5加密调用(先加密+乱序)NSLog(@"%@",[@"520it" hmacMD5StringWithKey:@"xiaomage"]);
对称加密算法AES和DES

简单示例

/** *  加密字符串并返回base64编码字符串 * *  @param string    要加密的字符串 *  @param keyString 加密密钥 *  @param iv        初始化向量(8个字节) * *  @return 返回加密后的base64编码字符串 */- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;/** *  解密字符串 * *  @param string    加密并base64编码后的字符串 *  @param keyString 解密密钥 *  @param iv        初始化向量(8个字节) * *  @return 返回解密后的字符串 */- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;// 调用EncryptionTools *encrypt = [EncryptionTools sharedEncryptionTools];NSLog(@"%@",[encrypt encryptString:@"LN123" keyString:@"LN" iv:nil]);NSLog(@"%@",[encrypt decryptString:@"OPcTMDB5paivqtYo9Fj+hQ==" keyString:@"LN" iv:nil]);
非对称加密RSA

简单示例

// 公钥加密时调用类方法:+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey;+ (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey;// 私钥解密时调用类方法+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey;+ (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privacy; /** 调用 */NSString *str = [RSAUtil encryptString: @"LN" publicKey:RSA_Public_key];NSLog(@"RSA公钥加密数据-->\n%@",str); NSString *str1 = [RSAUtil decryptString:str privateKey:RSA_Privite_key];NSLog(@"RSA私钥解密数据-->%@",str1);

MAC上生成公钥、私钥的方法,及使用

 # MAC上生成公钥、私钥的方法 @code 1.打开终端,切换到自己想输出的文件夹下 2.输入指令:openssl(openssl是生成各种秘钥的工具,mac已经嵌入) 3.输入指令:genrsa -out rsa_private_key.pem 1024 (生成私钥,java端使用的) 4.输入指令:rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout (生成公钥) 5.输入指令:pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt(私钥转格式,在ios端使用私钥解密时用这个私钥) 注意:在MAC上生成三个.pem格式的文件,一个公钥,两个私钥,都可以在终端通过指令vim xxx.pem 打开,里面是字符串,第三步生成的私钥是java端用来解密数据的,第五步转换格式的私钥iOS端可以用来调试公钥、私钥解密(因为私钥不留在客户端) iOS端公钥加密私钥解密、java端公钥加密私钥解密,java端私钥加密公钥解密都容易做到,iOS不能私钥加密公钥解密,只能用于验签 @endcode
5.HTTPS基本使用

方案一:如果是自己使用NSURLSession来封装网络请求

// 1.创建sessionNSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];// 2.创建TaskNSURLSessionDataTask *dataTask = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://kyfw.12306.cn/otn"]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {     // 3.解析数据    NSLog(@"%@---%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],error);}];// 4.执行task[dataTask resume]; #pragma mark - 遵守<NSURLSessionDataDelegate>// 如果发送的请求是https的,那么才会调用该方法-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {    /**     判断服务器传给我们的信任的类型,只有是【服务器信任的时候,才安装证书】     NSURLSessionAuthChallengeDisposition 如何处理证书     NSURLAuthenticationMethodServerTrust 服务器信任     */    if(![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) {        return;    }    NSLog(@"%@",challenge.protectionSpace);    /*     NSURLCredential 授权信息     NSURLSessionAuthChallengeUseCredential = 0, 使用该证书 安装该证书     NSURLSessionAuthChallengePerformDefaultHandling = 1, 默认采用的方式,该证书被忽略     NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2, 取消请求,证书忽略     NSURLSessionAuthChallengeRejectProtectionSpace = 3,          拒绝     */    NSURLCredential *credential = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];    completionHandler(NSURLSessionAuthChallengeUseCredential,credential);    // 注意:并不是所有的https的请求都需要安装证书(授权)的,请求一些大型的网站有的是强制安装的,如:苹果官网https://www.apple.com}

方案二:如果使用AFN网络请求

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; // 更改解析方式(请求网页源码应使用原始解析)manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // 设置对证书的处理方式// 允许自签名证书,必须的manager.securityPolicy.allowInvalidCertificates = YES;// 是否验证域名的CN字段(不是必须的,但是如果写YES,则必须导入证书)manager.securityPolicy.validatesDomainName = NO; [manager GET:@"https://kyfw.12306.cn/otn" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {     NSLog(@"success---%@",[[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding]);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {     NSLog(@"error---%@",error);}];
6.数据安全--加密解密效果
image

学习本文之外可以参考
网络安全——数据的加密与签名,RSA介绍
关于Https安全性问题、双向验证防止中间人攻击问题


写在最后,
曾经的曾经,
明天的你,一定会感谢今天拼命努力的自己!
附上一张图:

image image

时间有限,在这里还有好多地方 实战应用,没有总结写上,后续再做补充吧~
附上写的小样(Demo)
方法可直接拿走使用,如果你喜欢或有帮助,可否给个 Star

后续
学习总结-->GitHub(现在代码少点,总结好 待上传)、白开水ln-简书
不定时、持续更新、一些 学习心得与文章、实战应用~


我也是对所花费时间的一个总结,「学习总结,一劳永逸」。有不足或不对之处,乐听你的槽点(和❤️) ~ 关注菜鸟成长(简书专题)_. 我会不定时更新一些学习心得与文章;

上一篇 下一篇

猜你喜欢

热点阅读