我不确定我的解决方案有多安全。
Rob Napier有一个非凡的框架 ( RNCryptor ) 可以在 iOS 和其他系统中进行加密和解密。
据我所知,他正在使用AES-CBC,这实际上是 CommonCryptor.h 的标准
但是,我的要求迫使我使用AES-CTR。两者都非常相似,所以理论上它必须是简单的。但事实并非如此。
CommonCryptor.h 周围缺乏相关信息。它是有史以来最糟糕的解释框架之一。
与CBC合作,您只需致电CCCrypt()
. 但是,要使用CTR ,您应该调用: CCCrytorCreate()
, CCCryptorUpdate()
, CCCryptorFinal(
) 和CCCryptorRelease()
尝试加密我的数据时,我每次都收到不同的数据,当然解密它的结果不正确。
我在第一种方法中遇到了两个大问题:密钥的长度和写入 dataOut 的字节数。
我对问题进行了排序:
1.- 32 个字符的 NSString 键
NSString *key = @"1234567890ABCDEFGHIJKLMNOPQRSTUV";
2.- 以所需长度剪切 dataOut
最后这是我的加密和解密代码:
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonKeyDerivation.h>
#import <Security/Security.h>
+ (NSMutableData*) encryptString: (NSString*) stringToEncrypt withKey: (NSString*) keyString
{
//Key to Data
NSData *key = [keyString dataUsingEncoding:NSUTF8StringEncoding];
//String to encrypt to Data
NSData *data = [stringToEncrypt dataUsingEncoding:NSUTF8StringEncoding];
// Init cryptor
CCCryptorRef cryptor = NULL;
// Alloc Data Out
NSMutableData *cipherData = [NSMutableData dataWithLength:data.length + kCCBlockSizeAES128];
//Empty IV: initialization vector
NSMutableData *iv = [NSMutableData dataWithLength:kCCBlockSizeAES128];
//Create Cryptor
CCCryptorStatus create = CCCryptorCreateWithMode(kCCEncrypt,
kCCModeCTR,
kCCAlgorithmAES,
ccPKCS7Padding,
iv.bytes, // can be NULL, because null is full of zeros
key.bytes,
key.length,
NULL,
0,
0,
kCCModeOptionCTR_BE,
&cryptor);
if (create == kCCSuccess)
{
//alloc number of bytes written to data Out
size_t outLength;
//Update Cryptor
CCCryptorStatus update = CCCryptorUpdate(cryptor,
data.bytes,
data.length,
cipherData.mutableBytes,
cipherData.length,
&outLength);
if (update == kCCSuccess)
{
//Cut Data Out with nedded length
cipherData.length = outLength;
//Final Cryptor
CCCryptorStatus final = CCCryptorFinal(cryptor, //CCCryptorRef cryptorRef,
cipherData.mutableBytes, //void *dataOut,
cipherData.length, // size_t dataOutAvailable,
&outLength); // size_t *dataOutMoved)
if (final == kCCSuccess)
{
//Release Cryptor
//CCCryptorStatus release =
CCCryptorRelease(cryptor ); //CCCryptorRef cryptorRef
}
return cipherData;
}
}
else
{
//error
}
return nil;
}
+ (NSString*) decryptData: (NSData*) data withKey: (NSString*) keyString
{
//Key to Data
NSData *key = [keyString dataUsingEncoding:NSUTF8StringEncoding];
// Init cryptor
CCCryptorRef cryptor = NULL;
//Empty IV: initialization vector
NSMutableData *iv = [NSMutableData dataWithLength:kCCBlockSizeAES128];
// Create Cryptor
CCCryptorStatus createDecrypt = CCCryptorCreateWithMode(kCCDecrypt, // operation
kCCModeCTR, // mode CTR
kCCAlgorithmAES, // Algorithm
ccPKCS7Padding, // padding
iv.bytes, // can be NULL, because null is full of zeros
key.bytes, // key
key.length, // keylength
NULL, //const void *tweak
0, //size_t tweakLength,
0, //int numRounds,
kCCModeOptionCTR_BE, //CCModeOptions options,
&cryptor); //CCCryptorRef *cryptorRef
if (createDecrypt == kCCSuccess)
{
// Alloc Data Out
NSMutableData *cipherDataDecrypt = [NSMutableData dataWithLength:data.length + kCCBlockSizeAES128];
//alloc number of bytes written to data Out
size_t outLengthDecrypt;
//Update Cryptor
CCCryptorStatus updateDecrypt = CCCryptorUpdate(cryptor,
data.bytes, //const void *dataIn,
data.length, //size_t dataInLength,
cipherDataDecrypt.mutableBytes, //void *dataOut,
cipherDataDecrypt.length, // size_t dataOutAvailable,
&outLengthDecrypt); // size_t *dataOutMoved)
if (updateDecrypt == kCCSuccess)
{
//Cut Data Out with nedded length
cipherDataDecrypt.length = outLengthDecrypt;
// Data to String
NSString* cipherFinalDecrypt = [[NSString alloc] initWithData:cipherDataDecrypt encoding:NSUTF8StringEncoding];
//Final Cryptor
CCCryptorStatus final = CCCryptorFinal(cryptor, //CCCryptorRef cryptorRef,
cipherDataDecrypt.mutableBytes, //void *dataOut,
cipherDataDecrypt.length, // size_t dataOutAvailable,
&outLengthDecrypt); // size_t *dataOutMoved)
if (final == kCCSuccess)
{
//Release Cryptor
//CCCryptorStatus release =
CCCryptorRelease(cryptor); //CCCryptorRef cryptorRef
}
return cipherFinalDecrypt;
}
}
else
{
//error
}
return nil;
}
调用它:
NSString *key = @"1234567890ABCDEFGHIJKLMNOPQRSTUV";
NSString *stringToEncrypt = @"Gabriel.Massana";
NSData* encrypted = [GM_AES128_CTR encryptString:stringToEncrypt withKey:key];
NSString *decrypted = [GM_AES128_CTR decryptData:encrypted withKey:key];
我发布我的解决方案是因为 Stackoverflow 中的 AES CTR 没有太多问题。同样,如果有人想检查它并告诉我是否有问题,将不胜感激。
这个解决方案有多安全?破解系统容易吗?为 AES-CTR 添加更多安全性的可能性是什么?