美文网首页
iOS学习-数据加密

iOS学习-数据加密

作者: 快乐的tomato | 来源:发表于2019-11-13 13:47 被阅读0次

    网络传输数据需要进行加密。

    一、对称算法

    1、什么是对称算法

    加密和解密都使用相同的密钥
    特性:
    速度快,适合对大数据加密。
    常见的有DES、3DES、AES。最常用的是AES。

    2、什么是AES加密

    高级加密标准,Advanced Encryption Standard的缩写。AES 是一个分组密码算法,旨在取代 DES 成为广泛使用的标准

    3、AES加密原理

    image.png

    4、在iOS中的实现

    #pragma mark - 2、对称加密:加密、解密
    -(void)aesTest{
        
        NSString *str = @"我是中国人";
        NSLog(@"原字符=%@",str);
        
        NSString *str1 = [self aesEncrypt:str] ;
        NSLog(@"aes加密后-%@",str1);
        
        NSString *str2 = [self aesDecrypt:str1];
        NSLog(@"aes解密后-%@",str2);
    }
    
    /*
     需要导入头文件
     #import <CommonCrypto/CommonDigest.h>
     #import <CommonCrypto/CommonCrypto.h>
    */
    // 秘钥key
    const NSString *AESKey = @"chsiahGHBh";
    
    -(NSString *)aesEncrypt:(NSString *)sourceStr{
        
        if (!sourceStr){
            return nil;
        }
        
        char keyPtr[kCCKeySizeAES256];
        bzero(keyPtr, sizeof(keyPtr));
        [AESKey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
         
        NSData *sourceData = [sourceStr dataUsingEncoding:NSUTF8StringEncoding];
        NSUInteger dataLength = [sourceData length];
        size_t buffersize = dataLength+kCCBlockSizeAES128;
        void *buffer = malloc(buffersize);
        size_t numBytesEncrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [sourceData bytes], dataLength, buffer, buffersize, &numBytesEncrypted);
         
        if (cryptStatus == kCCSuccess) {
            NSData *encryptData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
            //对加密后的二进制数据进行base64转码
            return [encryptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
        } else {
            free(buffer);
            return nil;
        }
        
    }
    
    -(NSString *)aesDecrypt:(NSString *)secretStr{
        
       if (!secretStr) {
            return nil;
        }
        //先对加密的字符串进行base64解码
        NSData *decodeData = [[NSData alloc] initWithBase64EncodedString:secretStr options:NSDataBase64DecodingIgnoreUnknownCharacters];
         
        char keyPtr[kCCKeySizeAES256 + 1];
        bzero(keyPtr, sizeof(keyPtr));
        [AESKey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
         
        NSUInteger dataLength = [decodeData length];
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        size_t numBytesDecrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [decodeData bytes], dataLength, buffer, bufferSize, &numBytesDecrypted);
        if (cryptStatus == kCCSuccess) {
            NSData *data = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
            NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            
            return result;
        } else {
            free(buffer);
            return nil;
        }
    }
    
    
    

    AES加密的细节还要和和后台商量。

    二、非对称算法

    算法公开,可逆的加密数据。一般服务器存私钥,客户端存公钥,且公钥是公开的。用公钥加密,就用私钥解密。用私钥加密,就用公钥解密。
    特性:
    速度慢,适合对小数据加密。
    非对称算法比对称算法安全。
    最常用的是RSA。

    1、什么是RSA?

    三个人一起发明了非对称算法,三个人名字的首字母分别是R、S、A,所以非对称算法加密就叫RSA加密。

    2、RSA加密原理

    1、找出两个‘很大’的质数:P & Q,一般长度是上百位。然后通过下面计算得到N和 M;
    N = P * Q
    M = (P - 1) * (Q - 1)
    2、找出整数E,E与M互质,即除了1之外,没有其他公约数
    3、找出整数D,使用ED除以M余1,即(ED) % M = 1
    4、经过上述准备工作之后,可以得到:
    E是公钥,负责加密
    D是私钥,,负责解密
    N负责公钥和私钥之间的联系
    5、加密算法,假定对X进行加密
    (X^E)%N = Y
    6、解密算法,根据‘费马小定理',可以使用以下公式完成解密
    (Y^D)%N = X

    画外音:看懂的就看,看不懂的略过,反正我是看不懂~~

    3、应用场景

    由于 对称算法和非对称算法的特性,一般

    1、用RSA算法加密并传输对称算法所需的密钥
    2、数据本身的加密和解密使用对称加密算法(AES)

    4、在iOS中的应用

    1、需求:

    SDK开发,使用RSA加密和后台进行数据交互,后台是PHP,公钥、私钥是后台高度,把公钥发给了我。
    要求:
    1、post请求,客户端放公钥,私钥放后台
    2、先将上传的参数进行排序,再进行MD5加盐加密。
    3、再将数据进行RSA加密。
    4、使用的密钥是1024位,要和后台统一,解密长度128,加密长度117
    5、rsa_public_key.pem文件后台给的

    至于没有用对称算法传输数据,这个是后台决定的,每个公司的加密方法和顺序都不一样,具体问题具体分析。

    4、遇到的问题
    1、'openssl/asn1.h' file not found‘

    解决方法:
    Header Search Paths 添加这种格式的路径
    "$(SRCROOT)/XSFH_game/Lib"

    image.png
    2、base编码发给后台,后台接收少+的问题

    我这边发给后台加密后的base64编码,后台接收后,base64编码中的+变成了空格,导致后台解码错误,这是后台的问题
    解决方法:
    PHP学习 base64_encode +号变空格

    3、后台数据接收到问题

    可能是php接收数据的问题,我放在HTTPBody里的传给它的是一字符串,后台说没法解析,要那种类似于json的格式,最后给它传了个如下格式的代码stringWithFormat:@"baseKey=%@",encryptedString]; ,baseKey可以随便写,就类似于json的key值

    NSString *encryptedString = [[XSFHRSATool shareInstance] encryptStr:paramStr WithRSAKeyType:KeyTypePublic];
    NSString *keyAndValue = [NSString  stringWithFormat:@"baseKey=%@",encryptedString];
    request.HTTPBody = [keyAndValue  dataUsingEncoding:NSUTF8StringEncoding];
    

    三、散列算法

    1、什么是散列算法

    散列算法是不可逆的,MD5是其代表,又称作指纹算法,摘要算法。

    • 特点:
      1、对任意的数据,会生成固定长度的字符串。一般是32位。
      2、相同数据的MD5值肯定一样,不同的数据会产生不同的字符串,但是重复的概率很小。
      3、不可逆的,加密后的值一般解不出来,但是现在也可以通过暴力破解。
    • 用途:
      1、计算MD5的值,用户可以验证从网络上下载的文件是否在下载的过程中被修改了
      2、一般用来加密密码

    2、MD5在iOS的应用

    #pragma mark - 3、散列加密
    -(void)MD5Test{
        
        NSString *str = @"我是中国人";
        NSString *str1 = [self md5EncryptWithString:str];
        NSLog(@"MD5加密=%@",str1);
    
    }
    //秘钥
    static NSString *encryptionKey = @"nha735n197nxn(N′568GGS%d~~9naei';45vhhafdjkv]32rpks;lg,];:vjo(&**&^)";
    
    - (NSString *)md5EncryptWithString:(NSString *)string{
        return [self md5:[NSString stringWithFormat:@"%@%@", encryptionKey, string]];
    }
    
    - (NSString *)md5:(NSString *)string{
        
        const char *cStr = [string UTF8String];
        unsigned char digest[CC_MD5_DIGEST_LENGTH];
        CC_MD5(cStr, (CC_LONG)strlen(cStr), digest);
        NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
        for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
            [result appendFormat:@"%02X", digest[i]];
        }
        
        return result;
    }
    

    3、MD5更加安全的加密方式

    • HMAC:
      进行2次MD5加密。
      A = 原密码+一个字符串 进行混合 进行MD5计算
      B = A +原密码 再进行MD5计算
      最后B就是MD5加密的结果。
    • MD5 + 时间
      1、A = (任意字符串进行MD5加密 + 用户密码)进行HMAC加密
      2、从服务获取时间到分的字符串time
      3、B = ( A + time)进行MD5加密
      最后B就是MD5加密的结果。

    怎么说呢,上面2种方式都是重复利用MD5加密
    还可以更复杂,不过要和后台商量好就行了。

    四、钥匙串

    通过系统提供的钥匙串功能,可以在本地对用户的信息进行保存。系统使用AES方式对密码加密。
    相对于NSUserDefaults、plist文件保存等一般方式,keychain保存更为安全。所以我们会用keyChain保存一些私密信息,比如密码、证书、设备唯一码(把获取到用户设备的唯一ID 存到keychain 里面这样卸载或重装之后还可以获取到id,保证了一个设备一个ID)等等。

    一般使用第三方框架SSKeychain

    #pragma mark - 4、SSKeychain
    -(void)SSKeychainTest{
        
       [SSKeychain setPassword:@"admin123" forService:[NSBundle mainBundle].bundleIdentifier account:@"张三"];
       
       NSString *mima = [SSKeychain passwordForService:[NSBundle mainBundle].bundleIdentifier account:@"张三"];
        
       NSLog(@"输出密码=%@",mima);
    }
    
    

    参考:
    iOS AES加密
    1、RSA加密、解密、签名、验签的原理及方法
    2、一篇文章彻底弄懂Base64编码原理
    3、iOS中使用基于RSA使用公钥加密和公钥解密
    4、iOS RSA加签和验签(SHA1WithRSA)
    5、iOS MD5加密

    相关文章

      网友评论

          本文标题:iOS学习-数据加密

          本文链接:https://www.haomeiwen.com/subject/pduxictx.html