如何在iOS的AES加密中添加盐并使用目标c对其解密 [英] How to add salt to AES Encryption in iOS and decrypting it using objective c
问题描述
我通过在iOS中使用目标c将IV附加到AES加密/解密代码中,并能够对其进行解密和加密.现在,我正在尝试将盐添加到AES加密中,但是很不幸,它对我不起作用.这是代码:我还使用Android盐生成代码进行了编辑,目的只是为了检查我的盐生成在iOS中是否有效
I have appended the IV to the AES Encryption/decryption code by using objective c in iOS and able to decrypt and encrypt the same. Right now I am trying to add the salt to the AES Encryption but unfortunately its not working for me. Here is the code: I have also edited with Android salt generation code for just to check whether my salt generation is valid or not in iOS
加密代码:
+ (NSData*)encryptData:(NSData*)data key:(NSData*)key error:(NSError **)error;
{
NSData *salt = [self randomDataOfLength:16];
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 cryptBytes = 0;
NSMutableData *dataOut = [NSMutableData dataWithLength:ivLength + data.length + kCCBlockSizeAES128];
int status = SecRandomCopyBytes(kSecRandomDefault, ivLength, dataOut.mutableBytes);
NSLog(@"Data Out String Encrypt%@", dataOut);
NSLog(@"Status ID Engrypt%d", status);
if (status != 0) {
*error = [NSError errorWithDomain:@"ivError" code:status userInfo:nil];
return nil;
}
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES,
kCCOptionPKCS7Padding,
key.bytes,
key.length,
dataOut.bytes,
data.bytes,
data.length,
dataOut.mutableBytes + ivLength, dataOut.length,
&cryptBytes);
if (ccStatus == kCCSuccess) {
dataOut.length = cryptBytes + ivLength;
}
else {
if (error) {
*error = [NSError errorWithDomain:@"kEncryptionError" code:ccStatus userInfo:nil];
}
dataOut = nil;
}
return dataOut;
}
解密代码:
+ (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;
}
生成随机盐和算法.
+ (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:32];
int
result = CCKeyDerivationPBKDF(kCCPBKDF2, // algorithm
password.UTF8String, // password
[password lengthOfBytesUsingEncoding:NSUTF8StringEncoding], // passwordLength
salt.bytes, // salt
salt.length, // saltLen
kCCPRFHmacAlgSHA1, // PRF
10000, // 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;
}
我已经基于链接在此处输入链接描述,但是不幸的是,我得到了解密输出为nil
I have done all these based on the link enter link description here But unfortunately I am getting the output of decryption as nil
请指出哪里做错了吗?
我已经从Encrypt方法中删除了Salt生成代码.我将代码移到了 ViewController.m ,这是代码:
I have removed the Salt generation code from the Encrypt method . I moved the code to the ViewController.m here is the code:
NSString *myScretString = @"My encryption string";
NSData *salt = [FBEncryptorAES randomDataOfLength:16];
NSData *key1 = [FBEncryptorAES AESKeyForPassword:@"E8E033BC691W5F092BB5909933636552" salt:salt];
NSData* encryptedData = [FBEncryptorAES encryptData:[myScretString dataUsingEncoding:NSUTF8StringEncoding]
key:key1
error:&error];
NSLog(@"encryptedWithDynamicIV: %@", [encryptedData base64EncodedStringWithOptions:0]);
NSData* decryptedData = [FBEncryptorAES decryptData:encryptedData
key: key1
error:&error];
NSLog(@"decryptedWithDynamicIV: %@", [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding]);
这是Android SALT生成代码:
Here is the Android SALT generation code :
private static final String ALGORITHM = "AES";
private static final String MODE = "AES/CBC/PKCS5Padding";
private static final String KEY = "5909E8E0335F092BBBC699336365521W";
byte[] salt = generateSalt();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(KEY.toCharArray(), salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKeySpec = new SecretKeySpec(tmp.getEncoded(), ALGORITHM);
推荐答案
您正在扩展加密密钥,但没有扩展解密密钥.解密代码从不调用AESKeyForPassword
,而且我看不到您将盐存储到任何地方以将其发送给解密器的方式(将IV发送给解密器的方式).您不能仅将PBKDF2应用于一侧.这给您完全不同的键.
You're stretching your encryption key, but you're not stretching your decryption key. The decryption code never calls AESKeyForPassword
, and I don't see anywhere that you store the salt to send it to the decryptor (the way you send the IV to the decryptor). You can't just apply PBKDF2 to one side. That gives you completely different keys.
这篇关于如何在iOS的AES加密中添加盐并使用目标c对其解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!