【发布时间】:2021-02-17 20:08:11
【问题描述】:
我计划在我的应用程序中实施 AES 加密,为此我阅读了 Rob Napier 的内容丰富的教程:
这是一篇精彩的文章,我可以使用以下方法加密几个字符串:
使用 ROB NAPIER RNCRYPTOR 类
NSString * const
kRNCryptManagerErrorDomain = @"net.robnapier.RNCryptManager";
const CCAlgorithm kAlgorithm = kCCAlgorithmAES128;
const NSUInteger kAlgorithmKeySize = kCCKeySizeAES128;
const NSUInteger kAlgorithmBlockSize = kCCBlockSizeAES128;
const NSUInteger kAlgorithmIVSize = kCCBlockSizeAES128;
const NSUInteger kPBKDFSaltSize = 8;
const NSUInteger kPBKDFRounds = 10000; // ~80ms on an iPhone 4
// ===================
+ (NSData *)encryptedDataForData:(NSData *)data
password:(NSString *)password
iv:(NSData **)iv
salt:(NSData **)salt
error:(NSError **)error {
NSAssert(iv, @"IV must not be NULL");
NSAssert(salt, @"salt must not be NULL");
*iv = [self randomDataOfLength:kAlgorithmIVSize];
*salt = [self randomDataOfLength:kPBKDFSaltSize];
NSData *key = [self AESKeyForPassword:password salt:*salt];
size_t outLength;
NSMutableData *
cipherData = [NSMutableData dataWithLength:data.length +
kAlgorithmBlockSize];
CCCryptorStatus
result = CCCrypt(kCCEncrypt, // operation
kAlgorithm, // Algorithm
kCCOptionPKCS7Padding, // options
key.bytes, // key
key.length, // keylength
(*iv).bytes,// iv
data.bytes, // dataIn
data.length, // dataInLength,
cipherData.mutableBytes, // dataOut
cipherData.length, // dataOutAvailable
&outLength); // dataOutMoved
if (result == kCCSuccess) {
cipherData.length = outLength;
}
else {
if (error) {
*error = [NSError errorWithDomain:kRNCryptManagerErrorDomain
code:result
userInfo:nil];
}
return nil;
}
return cipherData;
}
// ===================
+ (NSData *)randomDataOfLength:(size_t)length {
NSMutableData *data = [NSMutableData dataWithLength:length];
int result = SecRandomCopyBytes(kSecRandomDefault,
length,
data.mutableBytes);
NSAssert(result == 0, @"Unable to generate random bytes: %d",
errno);
return data;
}
// ===================
// Replace this with a 10,000 hash calls if you don't have CCKeyDerivationPBKDF
+ (NSData *)AESKeyForPassword:(NSString *)password
salt:(NSData *)salt {
NSMutableData *
derivedKey = [NSMutableData dataWithLength:kAlgorithmKeySize];
int
result = CCKeyDerivationPBKDF(kCCPBKDF2, // algorithm
password.UTF8String, // password
[password lengthOfBytesUsingEncoding:NSUTF8StringEncoding], // passwordLength
salt.bytes, // salt
salt.length, // saltLen
kCCPRFHmacAlgSHA1, // PRF
kPBKDFRounds, // rounds
derivedKey.mutableBytes, // derivedKey
derivedKey.length); // derivedKeyLen
// Do not log password here
NSAssert(result == kCCSuccess,
@"Unable to create AES key for password: %d", result);
return derivedKey;
}
但是在解密时我无法正确解密,并且在场景中我得到空值:供您参考,解密代码是:
+ (NSData*)decryptData:(NSData*)data key:(NSData*)key error:(NSError **)error
{
if (key.length != 16 && key.length != 24 && key.length != 32) {
*error = [NSError errorWithDomain:@"keyLengthError" code:-1 userInfo:nil];
return nil;
}
CCCryptorStatus ccStatus = kCCSuccess;
int ivLength = kCCBlockSizeAES128;
size_t clearBytes = 0;
NSMutableData *dataOut = [NSMutableData dataWithLength:data.length - ivLength];
NSLog(@"Data Out String Decrypt%@", dataOut);
ccStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES,
kCCOptionPKCS7Padding,
key.bytes,
key.length,
data.bytes,
data.bytes + ivLength,
data.length - ivLength,
dataOut.mutableBytes,
dataOut.length,
&clearBytes);
if (ccStatus == kCCSuccess) {
dataOut.length = clearBytes;
}
else {
if (error) {
*error = [NSError errorWithDomain:@"kEncryptionError" code:ccStatus userInfo:nil];
}
dataOut = nil;
}
return dataOut;
}
在这种情况下我哪里出错了?我已经尝试了几天来解决它。有人可以帮帮我吗?
【问题讨论】:
-
stackoverflow.com/questions/64679465/… 这是我之前发布的问题,以防您需要更多说明,但我无法像 IV 一样添加盐值...所以请建议我使用正确的代码...这会更有帮助
-
简而言之,我只想在(IV + 密文)之前添加盐,然后用它来解密
-
当这个
;在你的代码中的实现端,那么任何结果都必须为零。 -
是的,但我仍然没有得到正确的解密,它返回 nil ...。我正在使用 salt 和 IV 寻找一个好的解密代码......所以如果你能帮助我请这将非常有用
-
为什么在加密时加减 BlockSizeAES128?您是否尝试仅加密最后一个字节?
标签: ios objective-c xcode commoncrypto