iOS 加解密

示例代码

MD5加密

MD5加密的特点:

  • 不可逆运算
  • 对不同的数据加密的结果是定长的32位字符(不管文件多大都一样)
  • 对相同的数据加密,得到的结果是一样的(也就是复制)。
  • 抗修改性 : 信息“指纹”,对原数据进行任何改动,哪怕只修改一个字节,所得到的 MD5 值都有很大区别.
  • 弱抗碰撞 : 已知原数据和其 MD5 值,想找到一个具有相同 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];
}

对称加密

简介:

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

加密解密过程:

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

优缺点:

  • 算法公开,计算量小,加密速度快,加密效率高
  • 双方使用相同的钥匙,安全性得不到保证

注意事项:

  • 密钥的保密工作非常重要
  • 密钥要求定期更换

经典加密算法:

  • DES(Data Encryption Standard):数据加密标准(现在用的比较少,因为它的加密强度不够,能够暴力破解)
  • 3DES:原理和DES几乎是一样的,只是使用3个密钥,对相同的数据执行三次加密,增强加密强度。(缺点:要维护3个密钥,大大增加了维护成本)
  • AES(Advanced Encryption Standard):高级加密标准,目前美国国家安全局使用的,苹果的钥匙串访问采用的就AES加密。是现在公认的最安全的加密方式,是对称密钥加密中最流行的算法。

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. 即使知道了客户端的加密算法和解密秘钥没有后台的随机因子,密码也是不会被破解。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值