iOS:密码学(对称加密)
Page content
数据的加密方和解密方共用一个相同的密钥来进行对数据的加解密
概要
本篇内容主要说明对称加密算法(AES)的使用。
算法特点
- 传统加密算法,加密可逆(解密);
- 加密和解密使用同一个密钥(密钥的保密从而变得尤为重要,密钥一般会定期更换)。
经典算法
- DES:数据加密标准(加密强度不够,用的较少);
- 3DES:使用三个密钥,对相同的数据进行三次加密(密钥管理非常麻烦,用的较少);
- AES:高级密码标准(美国国家安全局加密标准,现有手段暴力破解需要2000万年)。
加密方式
- ECB:电子代码本,每一个数据块独立加密;
- CBC:密码块链,使用一个密钥和一个初始化向量(IV)对数据进行加密。每一个数据块的加密依赖于上一个数据块。
AES
实现说明
- 支持的AES key size 有 128位,192位,256位;
- 数据填充方式:kCCOptionPKCS7Padding;
- 分组模式:cbc, ecb,具体实现封装为NSData的Category;
先引入头文件:
~~~objective-c
#import "NSData+AES.h"
#import <CommonCrypto/CommonCryptor.h>
~~~
CBC加密
AES CBC模式加密需要一个key和一个向量iv;
key 长度16字节,24字节,32字节,iv 16字节:
~~~objective-c
/**
AES cbc 加密
@param key 长度16字节,24字节,32字节
@param iv 16字节
@return 加密结果data
*/
- (NSData *)AESCBCEncryptWith:(NSData *)key iv:(NSData *)iv {
NSData *retData = nil;
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
bzero(buffer, bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
key.bytes, key.length,
iv.bytes,
self.bytes, self.length,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
retData = [NSData dataWithBytes:buffer length:numBytesEncrypted];
}
free(buffer);
return retData;
}
~~~
CBC解密
```objective-c
/**
AES cbc 解密
@param key 长度16字节,24字节,32字节
@param iv 16字节
@return 解密结果data
*/
- (NSData *)AESCBCDecryptWith:(NSData *)key iv:(NSData *)iv {
NSData *retData = nil;
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
bzero(buffer, bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
key.bytes, key.length,
iv.bytes,
self.bytes, self.length,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
retData = [NSData dataWithBytes:buffer length:numBytesEncrypted];
}
free(buffer);
return retData;
}
```
ECB加密
```objective-c
/**
AES ecb 加密
@param key 长度16字节,24字节,32字节
@return 加密结果data
*/
- (NSData *)AESECBEncryptWith:(NSData *)key {
NSData *retData = nil;
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
bzero(buffer, bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding|kCCOptionECBMode,
key.bytes, key.length,
NULL,
self.bytes, self.length,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
retData = [NSData dataWithBytes:buffer length:numBytesEncrypted];
}
free(buffer);
return retData;
}
```
ECB解密
```objective-c
/**
AES ecb 解密
@param key 长度16字节,24字节,32字节
@return 解密结果data
*/
- (NSData *)AESECBDecryptWith:(NSData *)key {
NSData *retData = nil;
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
bzero(buffer, bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding|kCCOptionECBMode,
key.bytes, key.length,
NULL,
self.bytes, self.length,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
retData = [NSData dataWithBytes:buffer length:numBytesEncrypted];
}
free(buffer);
return retData;
}
```
总结
对称加密是一种高效的加密方式,AES加密方式是其中最为安全有效的一种;
但由于对称加密的特点:加密方和解密方共用同一个密钥进行加解密操作,因此对于密钥的保存尤为重要,在实际生产环境中,经常配合RSA进行体系加密,由RSA加密AES的key,发放到客户端解密,客户端拿到key后再进行AES的加密传输。