iOS之数据安全加密

Base64编码
  • 可以将任意的二进制数据进行Base64编码
  • 被编码的数据只用65个字符就能表示成文本文件
  • 原理
    • 将所有的字符转化成ASCII
    • 在将对应的ASCII码转为8位二进制
    • 然后对二进制进行归组,每3个归为一组,不足3个的补e,这样变成了24位,在对其拆分成4组,每组6
    • 统一在6位二进制前补2个0组成8位,然后将二进制转为十进制
    • 最后在Base64编码表中获取十进制对应的base64编码
编码和解码

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    //编码
    
    NSLog(@"%@",[self base64EncodeStrng:@"测试"]);
    
 
    //解码
    
    NSString *base64 = [self base64EncodeStrng:@"测试"];
    NSLog(@"----%@",[self base64DecodeStrng:base64]);
    
    
}

在这里插入图片描述

编码

//编码
- (NSString *)base64EncodeStrng:(NSString *)string {
    
    //1.转化为二进制数据
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    //2.对数据进行编码

    return [data base64EncodedStringWithOptions:0];
    
}


解码

//解码

- (NSString *)base64DecodeStrng:(NSString *)string {
    
    //1.转化为二进制数据
    NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0];
   
    //转化为字符串
    
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
}

哈希(散列)函数 加密
  • 哈希(散列)函数
    • MD5
    • SHA1
    • SHA256/SHA512
1.散列函数

特点

  • 算法是公开的
  • 对不同的数据加密,得到的结果是定长的,MD5对不同的数据加密,得到的结果都是32个字符长的字符串
  • 不能反算
1.1 MD5加密
  • 加盐:就是一段固定的无序的字符和你要加密的字符,拼接在一起
  • 注意:固定的一旦被知道,那么加密的安全系数,就会大大的降低,所以一般加盐的方式不适用了,

static NSString *str = @"cnwuikjkads";

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //加盐:就是一段固定的无序的字符和你要机密的字符,拼接在一起
    
    NSString *md5Str = @"测试";
    
   md5Str =  [md5Str stringByAppendingString:str];
    
    NSLog(@"%@",[md5Str md5String]);
   
   //打印结果: 2dcee1e9cbef28254ea01ff0b6f80c62
    
    
}


- (NSString *)md5String {
//转为C语言的字符串
    const char *str = self.UTF8String;
    
    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
   
    //MD5加密计算
    CC_MD5(str, (CC_LONG)strlen(str), buffer);
    
    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}



//转化OC语言的字符串
- (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];
}

1.2SHA1加密

- (NSString *)sha1String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA1_DIGEST_LENGTH];
    
    CC_SHA1(str, (CC_LONG)strlen(str), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA1_DIGEST_LENGTH];
}
1.3 SHA256/SHA512加密

// SHA256
- (NSString *)sha256String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA256_DIGEST_LENGTH];
    
    CC_SHA256(str, (CC_LONG)strlen(str), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
}


// SHA512加密
- (NSString *)sha512String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA512_DIGEST_LENGTH];
    
    CC_SHA512(str, (CC_LONG)strlen(str), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA512_DIGEST_LENGTH];
}

为了弥补加盐被泄露,所以有了HMAC,它是给定一个密钥进行2次MD5加密,这里的密钥一般是从服务器请求获取

HMAC 散列碰撞 加密

//HMAC加密 key是密钥
- (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);
    
    //转化成OC的字符串
    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}



- (NSString *)hmacSHA1StringWithKey:(NSString *)key {
    const char *keyData = key.UTF8String;
    const char *strData = self.UTF8String;
    uint8_t buffer[CC_SHA1_DIGEST_LENGTH];
    
    CCHmac(kCCHmacAlgSHA1, keyData, strlen(keyData), strData, strlen(strData), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA1_DIGEST_LENGTH];
}

- (NSString *)hmacSHA256StringWithKey:(NSString *)key {
    const char *keyData = key.UTF8String;
    const char *strData = self.UTF8String;
    uint8_t buffer[CC_SHA256_DIGEST_LENGTH];
    
    CCHmac(kCCHmacAlgSHA256, keyData, strlen(keyData), strData, strlen(strData), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
}

- (NSString *)hmacSHA512StringWithKey:(NSString *)key {
    const char *keyData = key.UTF8String;
    const char *strData = self.UTF8String;
    uint8_t buffer[CC_SHA512_DIGEST_LENGTH];
    
    CCHmac(kCCHmacAlgSHA512, keyData, strlen(keyData), strData, strlen(strData), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA512_DIGEST_LENGTH];
}

为了用户登录或者注册的时候,我们保存用户名或者密码,最好不要用NSUserDefaults,一般使用钥匙串保存,就用到一个 SSKeychain钥匙串保存用户密码
在使用 SSKeychain的时候,要先开启

在这里插入图片描述

  • 保存密码到钥匙串
- (IBAction)SaveSSKeyAction:(UIButton *)sender {
    //保存账号
    NSString *account = @"JC";
    [[NSUserDefaults standardUserDefaults] setObject:account forKey:@"account_key"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    NSString *psd = @"12345";
    
    //保存在钥匙串
    //参数一:要保存的密码
    //参数二:服务可以自己定义,也可以是APP的标识
    //参数三:账号
    //参数四:返回的error
    BOOL isScu = [SSKeychain setPassword:psd forService:@"com.cc.jc" account:account error:nil];
    
    NSLog(@"%@",isScu == YES ?@"成功":@"失败");
    
}

  • 取出保存在钥匙串的密码

- (IBAction)getPsdAction:(UIButton *)sender {
    //保存成功
    //出去数据
    NSString *account = [[NSUserDefaults standardUserDefaults] objectForKey:@"account_key"];
    
    //从钥匙串中取出
    NSString *psd = [SSKeychain passwordForService:@"com.cc.jc" account:account];
    
    NSLog(@"%@",psd);
    
}


对称加密
  • 对称加密算法
    • DES 数据加密标准
    • 3DES :使用3个秘钥,对相同的数据来加密3次,增加安全系数
    • AES:这个一般是比较高级的加密,
  • 有2种加密的方式
    • ECB:把每一个数据块独立加密,然后拼接在一起,在解密的时候也是先拆分数据块,然后独立解密数据块
    • CBC:加密每一个数据块,都会与上一个数据块之前有联系,
ECB 数据块 加密

测试对称加密,我们打开终端 1.进入桌面cd Desktop/ 2.查看桌面内容ls 3.想对桌面的某个文件进行编辑vim 100.txt 编辑100.txt文件

在这里插入图片描述

openssl enc -des-ecb -K 616263 - nosalt -in 110.txt -out msg1.bin 这个是对称机密的一个命令行,其中openssl是一个标准的加密库,enc是加密方式,-des-ecb表示是DES加密中的ECB加密方式, -K 616263 是key对应的16进制的ASII码是ABC, nosalt是不加盐,后面是-in 110.txt对这个文件进行加密, -out msg1.bin输出加密文件

查看加密
在这里插入图片描述

CBC 数据块 加密
  • 110.txtCBC数据块加密,

openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -in 110.txt -out msg2.bin
命令行中的 -iv是字面向量

在这里插入图片描述

代码创建加密
  • 这其中用到一个工具类EncryptionTools来完成加密
代码 ECB加密
//ECB加密
- (void)setupECB{
    //创建 秘钥
    NSString *key = @"ABC";
    NSString *ecbStr = @"你好";
   //加密之后返回的是一个 base64格式的字符串
   NSString *bsae64Str = [[EncryptionTools sharedEncryptionTools] encryptString:ecbStr keyString:key iv:nil];
    
    NSLog(@"ECB:---%@",bsae64Str);
    
    //结果: ECB:---8+0WsGSH5h1bYWE5FQjgYg==
    
    //解密
   NSString *decBase64Str = [[EncryptionTools sharedEncryptionTools] decryptString:bsae64Str keyString:key iv:nil];
    
     NSLog(@"解密:---%@",decBase64Str);
    //结果:解密:---你好
    
}

代码 CBC加密
//CBC加密
- (void)setupCBC{
    //创建 秘钥
    NSString *key = @"ABC";
    NSString *ecbStr = @"你好";
   //向量
    uint8_t iv[8] = {3,4,5,6,7,8,9,0};
    NSData *ivData = [NSData dataWithBytes:iv length:sizeof(iv)];
    //加密之后返回的是一个 base64格式的字符串
    NSString *bsae64Str = [[EncryptionTools sharedEncryptionTools] encryptString:ecbStr keyString:key iv:ivData];
    
    NSLog(@"ECB:---%@",bsae64Str);
    //打印结果:ECB:---B9Rh6e+m7BhpWGBcAKUZUw==
    
    //解密
    NSString *decBase64Str = [[EncryptionTools sharedEncryptionTools] decryptString:bsae64Str keyString:key iv:ivData];
    
    NSLog(@"解密:---%@",decBase64Str);
    //打印结果:解密:---你好
}


非对称加密算法(RSA)
  • 公钥秘钥的加密方式,用公钥加密就得用秘钥解密,反之用秘钥加密就得有公钥解密
  • 这种加密方式一般在支付类的APP使用的比较频繁
前期准备工作

打开终端进入桌面cd Desktop/ 在桌面上新建一个RSA文件 用来存储 生成的公钥,秘钥和证书

进入 cd RSA文件

在使用终端的时候,psd来看查看现在所在的文件路径

在这里插入图片描述

1. 用命令行 生成私钥

openssl genrsa -out private.pem 512

在这里插入图片描述

2. 用命令行 生成公钥

openssl rsa -in private.pem -out public.pem -pubout

cat private.pem 查看秘钥

3. 创建请求证书
  • 生成.csr文件

openssl req -new -key private.pem -out resacert.csr

在这个过程中 需要填写一些信息

国家名称
Country Name (2 letter code) []: CN

省份
State or Province Name (full name) []: shanghai

上海
Locality Name (eg, city) []:

机构名称
Organization Name (eg, company) []:

单位名称
Organizational Unit Name (eg, section) []:

主机名
Common Name (eg, fully qualified host name) []:

邮箱地址
Email Address []:

密码
A challenge password []:

注意这个密码一定要记住!!!!!!!,因为在加载私钥的时候需要密码输入

4. 把 生成的resacert.csr证书转化为 数字证书(reacert.crt)
  • 命令行如下:

openssl x509 -req -days 3650 -in reacert.csr -signkey private.pem -out reacert.crt

5. 把数字证书 转化 der证书(二进制) 这样苹果可以识别
  • 因为3和4生成的证书 都是16进制

  • 命令行如下:

openssl x509 -outform der -in reacert.crt -out reacert.der

6. 把数字证书转化为p12文件

openssl pkcs12 -export -out p.p12 -inkey private.pem -in reacert.crt

p生成p12文件的名称,-inkey对应的秘钥是private.pem

在这里插入图片描述

7. 获取公钥私钥

吧生成的公钥和私钥拖入工程。-----> 使用RSACryptor这个工具类,来对数据进行加密和解密

加载公钥和秘钥 ~ 注意!!!!:在加载私钥时 需要你在创建过程中输入的密码


- (void)viewDidLoad {
    [super viewDidLoad];
    

    
    //获取公钥
    NSString *filepath = [[NSBundle mainBundle] pathForResource:@"reacert.der" ofType:nil];
    
    [[RSACryptor sharedRSACryptor] loadPublicKey:filepath];
    
    //y私钥
    NSString *privatePath = [[NSBundle mainBundle] pathForResource:@"p.p12" ofType:nil];
    [[RSACryptor sharedRSACryptor] loadPrivateKey:privatePath password:@"123456"];
    
   
   
}

7. 加密和解密
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    //需要加密的字符串
    //比如:支付密码
    NSData *psdData = [@"123456" dataUsingEncoding:NSUTF8StringEncoding];
    
     NSData *resultData = [[RSACryptor sharedRSACryptor] encryptData:psdData];
    NSLog(@"RSA加密的二进制数据:----%@",resultData);
     NSString *base64Str = [resultData base64EncodedStringWithOptions:0];
    
    NSLog(@"二进制数据对应的64的字符串:%@",base64Str);
    
    
    NSData *d_data = [[RSACryptor sharedRSACryptor] decryptData:resultData];
    
   NSString *psd = [[NSString alloc] initWithData:d_data encoding:NSUTF8StringEncoding];
    
    NSLog(@"密码:----%@",psd);
    
    
}


  • 打印结果:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值