iOS 加解密

2019-08-14  本文已影响0人  酒茶白开水

示例代码

MD5加密

MD5加密的特点:

MD5 应用:

一致性验证:MD5将整个文件当做一个大文本信息,通过不可逆的字符串变换算法,产生一个唯一的MD5信息摘要,就像每个人都有自己独一无二的指纹,MD5对任何文件产生一个独一无二的数字指纹。

注意点:加盐

“盐”就是一串比较复杂的字符串。加盐的目的是加强加密的复杂度,这么破解起来就更加麻烦,当然这个“盐”越长越复杂,加密后破解起来就越麻烦。

算法实现:

// 0、引入框架
#import <CommonCrypto/CommonDigest.h>

- (NSString *)md5_32:(NSString *)text upperCase:(BOOL)uppuerCase {
    // 1、转化为UTF8字符串
    const char *chars = [text UTF8String];
    // 2、设置一个接收字符数组
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    
    // 3、把str字符串转换成为32位的16进制数列,存到result中
    CC_MD5(chars, (int)strlen(chars), digest);
    NSMutableString *result = [NSMutableString stringWithCapacity:1];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        // 4、将16字节的16进制转成32字节的16进制字符串
        [result appendFormat:@"%02x", digest[i]];
    }
    
    if (uppuerCase) {
        return [result uppercaseString];
    } else {
        return [result lowercaseString];
    }
}
- (NSString *)md5_16:(NSString *)text upperCase:(BOOL)uppuerCase  {
    NSString *md5_32 = [self md5_32:text upperCase:uppuerCase];
    
    // 从32位中提取9~24位
    return [[md5_32 substringToIndex:24] substringFromIndex:8];
}

对称加密

简介:

对称加密算法又称传统加密算法。
加密和解密使用同一个密钥。

加密解密过程:

明文->密钥加密->密文,密文->密钥解密->明文。

优缺点:

注意事项:

经典加密算法:

AES加密实现

// 导入框架
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>

// 对NSData加密
- (NSData *)AESEncryptWithData:(NSData *)data Key:(NSString *)key
{
    char keyPtr[kCCKeySizeAES128 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    char ivPtr[kCCBlockSizeAES128 + 1];
    memset(ivPtr, 0, sizeof(ivPtr));
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    
    if(cryptStatus == kCCSuccess)
    {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    
    free(buffer);
    
    return nil;
}

// 对NSData解密
- (NSData *)AESDecryptWithData:(NSData *)data andKey:(NSString *)key
{
    char keyPtr[kCCKeySizeAES128 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [data bytes], dataLength, buffer, bufferSize, &numBytesDecrypted);
    
    if(cryptStatus == kCCSuccess)
    {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }
    
    free(buffer);
    
    return nil;
}

// 对NSString加密(实际上是先把字符串转化为NSData进行加密,再把加密后的NSData转化为字符串)
- (NSString *)AESEncryptWithString:(NSString *)string andKey:(NSString *)key
{
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    
    //对数据进行加密
    NSData *result = [self AESEncryptWithData:data Key:key];
    NSLog(@"%@", result);
    
    NSData *endData = [result base64EncodedDataWithOptions:NSDataBase64Encoding64CharacterLineLength];
    return [[NSString alloc] initWithData:endData encoding:NSUTF8StringEncoding];
}

// 对NSString解密(实际上是先把字符串转化为NSData进行解密,再把解密后的NSData转化为字符串)
- (NSString *)AESDecryptWithString:(NSString *)string andKey:(NSString *)key
{
    NSData *result = [self AESDecryptWithData:[[NSData alloc] initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters] andKey:key];
    if(result && result.length > 0)
    {
        NSString *str = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
        
        return str;
    }
    
    return nil;
}

函数解析:

CCCryptorStatus CCCrypt(
    CCOperation op,         /* 用来代表加密或者解密,kCCEncrypt = 加密,kCCDecrypt = 解密 */
    CCAlgorithm alg,        /* 用来代表加密算法,有kCCAlgorithmAES128... */
    CCOptions options,      /* 填充模式,iOS中只提供了kCCOptionPKCS7Padding和kCCOptionECBMode两种,这个在于后台和安卓交互时要注意一点。 */
    const void *key,        /* 密钥长度,一般使用char keyPtr[kCCKeySizeAES256+1] */
    size_t keyLength,       /* 加密信息的比特数 */
    const void *iv,         /* 偏移向量,CBC模式下需要,不传默认16位0 */
    const void *dataIn,     /* 加解密的数据data.bytes */
    size_t dataInLength,    /* 加解密的数据的大小 */
    void *dataOut,          /* 用来输出加密结果 */
    size_t dataOutAvailable,/* 输出加密结果的大小 */
    size_t *dataOutMoved)   /* 输出加密结果的大小 */
    API_AVAILABLE(macos(10.4), ios(2.0));/* 缓冲区空间 */

在线加密验证

非对称加密RSA

简介:

  1. 对称加密算法又称现代加密算法。
  2. 非对称加密是计算机通信安全的基石,保证了加密数据不会被破解。
  3. 非对称加密算法需要两个密钥:公开密钥(publickey) 和私有密(privatekey)
  4. 公开密钥和私有密钥是一对

特点:

与对称加密算法的对比:

RSA应用场景:

由于RSA算法的加密解密速度要比对称算法速度慢很多,在实际应用中,通常采取数据本身的加密和解密使用对称加密算法(AES)。
用RSA算法加密并传输对称算法所需的密钥。

RSA实现

RSA的实现主要是使用Security.framework框架的SecKeyEncrypt和SecKeyDecrypt函数。

RSA具体实现

签名验签

签名验签理解

SHA1+RSA签名验签实现

主要使用到Security.framework框架的SecKeyRawSign函数与SecKeyRawVerify函数。

SHA1+RSA签名验签具体实现

加密方案

通讯加密方案:非对称加密+对称加密,例如RSA+AES、sm2+sm4。

每次通信客户端随机生成AES秘钥,用AES秘钥加密报文,用RSA共钥加密AES秘钥。将加密后的报文y以及一些必要信息包在头部发送到服务器。后台首先用RSA秘钥解密得到AES秘钥,再用AES秘钥解密报文。

虽然RSA加密算法的安全性很高,但是RSA加解密的速度非常慢而且RSA不能加密过长的报文,这就限制了单独使用RSA加密传输的报文。AES算法的安全性不及RSA但是对加密报文的长度是没有限制的而且加解密运算速度很快。

键盘加密

用户输入的密文采取一次一秘的方案。在每次密码输入键盘谈起之前向后台请求随机因子,用户密码的加密和随机因子以某种方式绑在一起。这就保证了:

  1. 同样的密码用户每次传输的秘文都是不一样的,被截取也是没有关系的。
  2. 即使知道了客户端的加密算法和解密秘钥没有后台的随机因子,密码也是不会被破解。
上一篇 下一篇

猜你喜欢

热点阅读