问题
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
Encryption code:
+ (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;
}
Decryption code :
+ (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;
}
Generating random salt and Algorithm..
+ (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;
}
I have done all these based on the link enter link description here But unfortunately I am getting the output of decryption as nil
Please suggest where am doing wrong?
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]);
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);
回答1:
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.
来源:https://stackoverflow.com/questions/64679465/how-to-add-salt-to-aes-encryption-in-ios-and-decrypting-it-using-objective-c