****场景****
公司接口安全需要RSA和AES混合使用,RSA已经走通,AES也预研成功。现将代码及注意事项贴出,以供大家研究学习
一、注意加密要求。我们使用的128byte的,看到加密参数128byte的要求,本人懵逼了,完全不知道是什么要求,问问服务端他也不太清楚,话说现在也没明白byte和bit有什么区别,然后有人告诉我128的要求是长度为16的字符串。同理256要求长度为32的字符,至于为什么要求是128,好像说是考虑兼容性的问题,新版本的不支持256的支持。也有人使用16位的MD5和32位的MD5,这里见仁见智,找到适合自己的就好。
二、填充模式。iOS系统加密方法 kCCOptionPKCS7Padding 和NOPadding的加密模式,NOPading不合适采用,所以我们使用 kCCOptionPKCS7Padding加密 ,但是JAVA不支持PKCS7Padding只支持PKCS5Padding ,可以通过导入一定的包处理(不懂JAVA稍后贴出同事的代码链接)
三、使用相同参数。在开发时候两边由于语言不一致,网上资料众说纷纭,在各自寻找适用自己加密解密方法后,在本地进行测试能很好地演示效果,但是一进入联调就会出现参数错误,格式不对等这样那样的问题导致接口不通。双方开始之前要了解使用加密模式的及传输要求。开始之前碰头了解下各自的需要。能有效的规避很多问题
****核心代码****
系统方法加密文件
#import <Foundation/Foundation.h>
@class NSString;
@interface NSData (Encryption)
- (NSData *)AES128EncryptWithKey:(NSString *)key; //加密
- (NSData *)AES128DecryptWithKey:(NSString *)key; //解密
@end
#import "NSData+AES.h"
#import <CommonCrypto/CommonCryptor.h>
#define gIv @"0102030405060708" //偏移量。可以自行修改,注意,128位要求字符长度为16个,
@implementation NSData (Encryption)
//(key和iv向量这里是16位的) 这里是CBC加密模式,安全性更高
- (NSData *)AES128EncryptWithKey:(NSString *)key {//加密
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCKeySizeAES128+1];
memset(ivPtr, 0, sizeof(ivPtr));
[gIv getCString:ivPtr maxLength:sizeof(ivPtr) 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,
keyPtr,
kCCBlockSizeAES128,
ivPtr,
[self bytes],
dataLength,
buffer,
bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData *)AES128DecryptWithKey:(NSString *)key {//解密
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCKeySizeAES128+1];
memset(ivPtr, 0, sizeof(ivPtr));
[gIv getCString:ivPtr maxLength:sizeof(ivPtr) 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,
keyPtr,
kCCBlockSizeAES128,
ivPtr,
[self bytes],
dataLength,
buffer,
bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
@end
暴露的使用方法
#import <Foundation/Foundation.h>
@interface SecurityUtil : NSObject
#pragma mark - base64
+ (NSString*)encodeBase64String:(NSString *)input;
+ (NSString*)decodeBase64String:(NSString *)input;
+ (NSString*)encodeBase64Data:(NSData *)data;
+ (NSString*)decodeBase64Data:(NSData *)data;
#pragma mark - AES加密
//将string转成带密码的data
+ (NSString*)encryptAESData:(NSString*)string app_key:(NSString*)key ;
//将带密码的data转成string
+(NSString*)decryptAESString:(NSString*)string app_key:(NSString*)key ;
@end
#import "SecurityUtil.h"
#import "GTMBase64.h"
#import "NSData+AES.h"
@implementation SecurityUtil
#pragma mark - base64
+ (NSString*)encodeBase64String:(NSString * )input {
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
data = [GTMBase64 encodeData:data];
NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
return base64String;
}
+ (NSString*)decodeBase64String:(NSString * )input {
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
data = [GTMBase64 decodeData:data];
NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
return base64String;
}
+ (NSString*)encodeBase64Data:(NSData *)data {
data = [GTMBase64 encodeData:data];
NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
return base64String;
}
+ (NSString*)decodeBase64Data:(NSData *)data {
data = [GTMBase64 decodeData:data];
NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
return base64String;
}
#pragma mark - AES加密
//将string转成带密码的data
+(NSString*)encryptAESData:(NSString*)string app_key:(NSString*)key
{
//将nsstring转化为nsdata
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
//使用密码对nsdata进行加密
NSData *encryptedData = [data AES128EncryptWithKey:key];
// NSString *astring=[encryptedData base64EncodedStringWithOptions:0];
// NSLog(@"加密后的字符串 :%@",astring);
return [encryptedData base64EncodedStringWithOptions:0];
}
#pragma mark - AES解密
//将带密码的data转成string
+(NSString*)decryptAESString:(NSString*)string app_key:(NSString*)key
{
NSData *EncryptData = [GTMBase64 decodeString:string]; //解密前进行GTMBase64编码
//使用密码对data进行解密
NSData *decryData = [EncryptData AES128DecryptWithKey:key];
//将解了密码的nsdata转化为nsstring
NSString *str = [[NSString alloc] initWithData:decryData encoding:NSUTF8StringEncoding];
return str;
}
@end
网友评论