最近在准备面试,发现之前项目中用到的加密技术都记得不清楚了,所以总结一下。之前项目用到的加密技术一种是DES加密,用来加密发送请求的字段,保证服务器数据的安全,一种是AES加密,用于加密登录时发送的账号密码数据。
一 . DES加密
DES加密属于对称加密算法,即信息的发送者与接受者在进行信息的传输与处理上使用的同一秘钥。
直接上代码,新建DESEncry文件,.h文件中:
#import <Foundation/Foundation.h>
@interface DESEncry : NSObject
/**
* @brief 对文本进行DES加密
*
* @param data 待加密的文本数据
* @param key 加密所有的公钥
* @param iv 加密向量
*
* @return 加密好的数据
*/
+ (NSData *)encryptUseDES:(NSString *)string key:(NSString *)key iv:(const void *)iv;
/**
* @brief 对文本进行DES解密
*
* @param data 待解密的数据
* @param key 解密所用的公钥
*
* @return 解密好的数据
*/
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key;
@end
.m文件:
#import "DESEncry.h"
#import <CommonCrypto/CommonCryptor.h>
@implementation DESEncry
+ (NSData *)encryptUseDES:(NSString *)string key:(NSString *)key iv:(const void *)iv
{
const char *textBytes = [string UTF8String];
NSUInteger dataLength = strlen(textBytes);
NSMutableData *data = [NSMutableData new];
NSUInteger n = dataLength / 1024;
for (int i = 0; i <= n;i++){
unsigned char buffer[1024];
unsigned char temp[1024];
memset(buffer, 0, sizeof(char));
memset(temp, 0, sizeof(char));
strncpy((char*)temp,textBytes, i==n?dataLength-1024*n:1024);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding|kCCOptionECBMode,
[key UTF8String], kCCKeySizeDES,
iv,
temp, i==n?dataLength-1024*n:1024,
buffer, 1024,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
[data appendData:[NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted]];
}
}
return data;
}
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+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, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
@end
项目中具体调用:
NSString *str=HOST;
_hostUrl = [str stringByAppendingString:@"opt=click&page=Login"];
NSDictionary * resultdic = @{@"pwd":pwd,@"uid":uid};
NSString *strReq = [TypeConversion jsonStringWithDictionary:resultdic];
//加密
Byte iv[] = {1,2,3,4,5,6,7,8};
NSData * data = [DESEncry encryptUseDES:strReq key:@"zywl9876" iv:iv];
NSString *str5 = [[NSString alloc] initWithData:[GTMBase64 encodeData:data] encoding:NSUTF8StringEncoding];
_paramDict = @{@"_json":str5};
二 . AES加密
AES也是属于对称加密算法,不过安全级别比DES高。
上代码,新建MySecurity文件,.h文件中
#import <Foundation/Foundation.h>
@interface MySecurity : NSObject
#pragma mark -根据密匙初始化
-(instancetype) initWithKey:(NSString *) key;
#pragma mark -加密
-(NSString *) AES256EncryptWithString:(NSString *) str;
#pragma mark -解密
-(NSString *) AES256DecryptWithString:(NSString *) str;
#pragma mark -获取安全密匙
+(NSString*) getSecurityKey;
@end
.m文件:
#import "MySecurity.h"
#import "NSData+AES256.h"
@interface MySecurity ()
@property(strong,nonatomic) NSString *key;
@end
@implementation MySecurity
#pragma mark -获取安全钥匙
+(NSString*) getSecurityKey
{
return @"KEY";
}
#pragma mark -更加密码密匙初始化
-(instancetype) initWithKey:(NSString *) key
{
self = [super init];
if (self)
{
self.key = key;
}
return self;
}
#pragma mark -加密
-(NSString *) AES256EncryptWithString:(NSString *) str
{
NSData *dt1 = [str dataUsingEncoding:NSUTF8StringEncoding];
NSData *dt2 = [dt1 AES256EncryptWithKey:self.key];
NSString *str2 = [dt2 base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
return str2;
}
#pragma mark -解密
-(NSString *) AES256DecryptWithString:(NSString *) str
{
NSData *dt3 = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSData *dt4 = [dt3 AES256DecryptWithKey:self.key];
NSString *str4 = [[NSString alloc] initWithData:dt4 encoding:NSUTF8StringEncoding];
return str4;
}
新建一个NSData的类别:
#import <Foundation/Foundation.h>
@interface NSData (AES256)
/*
加密
(NSString*)key 32位秘钥
返回加密后的 NSData
*/
- (NSData*)AES256EncryptWithKey:(NSString*)key ;
/*
解密
(NSString*)key 32位秘钥
返回解密后的 NSData
*/
- (NSData*)AES256DecryptWithKey:(NSString*)key ;
@end
.m文件
#import "NSData+AES256.h"
#import <CommonCrypto/CommonCryptor.h>
@implementation NSData (AES256)
- (NSData*)AES256EncryptWithKey:(NSString*)key {
char keyPtr[kCCKeySizeAES256 +1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding|kCCOptionECBMode,
keyPtr,
kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes],
dataLength, /* input */
buffer,
bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData*)AES256DecryptWithKey:(NSString*)key {
char keyPtr[kCCKeySizeAES256+1 ]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding|kCCOptionECBMode,
keyPtr,
kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes],
dataLength, /* input */
buffer,
bufferSize, /* output */
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer); //free the buffer;
return nil;
}
@end
项目中的具体调用:
MySecurity *security = [[MySecurity alloc] initWithKey:[MySecurity getSecurityKey]];
//AES加密
NSMutableDictionary*dic = [[NSMutableDictionary alloc]initWithObjectsAndKeys:self.userTF.text,@"LoginName",self.pswTF.text,@"Password", nil];
NSData*data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
NSString*dataStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSString * str1 = [security AES256EncryptWithString:dataStr];