I'm generating and exporting a key with CryptoJS:
const password = crypto.lib.WordArray.random(128 / 8);
const salt = crypto.lib.WordArray.random(128 / 8);
const encryptionKey = crypto.PBKDF2(password, salt, {keySize: 128 / 32});
return encryptionKey.toString();
Now I'm trying to encrypt some data with the key on iOS:
const char *s = [encryptionKey cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData= [NSData dataWithBytes:s length:strlen(s)];
NSMutableData *ivData = [NSMutableData dataWithLength:kCCBlockSizeAES128];
SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivData.mutableBytes);
NSData *iv = [NSData dataWithData:ivData];
size_t outLength;
NSMutableData *cipherData = [NSMutableData dataWithLength:dataString.length + kCCBlockSizeAES128];
CCCrypt(kCCEncrypt, // operation
kCCAlgorithmAES128, // Algorithm
kCCOptionPKCS7Padding, // options
keyData.bytes, // key
keyData.length, // keylength
iv.bytes,// iv
jsonData.bytes, // dataIn
jsonData.length, // dataInLength,
cipherData.mutableBytes, // dataOut
cipherData.length, // dataOutAvailable
&outLength); // dataOutMoved
cipherData.length = outLength;
NSString *cipherText = [cipherData base64EncodedStringWithOptions:NSUTF8StringEncoding];
NSString *ivText = [iv base64EncodedStringWithOptions:NSUTF8StringEncoding];
return [ivText stringByAppendingString:cipherText]
This all works so far. Trying to decrypt the data with CryptoJS however fails:
const iv = crypto.enc.Base64.parse(message.substr(0, 24));
const encrypted = crypto.enc.Base64.parse(message.substring(24));
const decrypted = crypto.AES.decrypt(encrypted, encryptionKey, {
iv: iv,
padding: crypto.pad.Pkcs7,
mode: crypto.mode.CBC
});
console.log(decrypted.toString(crypto.enc.Utf8))
The problem seems to be in the passing of the key from CryptoJS to iOS. What is the correct format to pass to CCCrypt?
The option to base64EncodedStringWithOptions
is incorrect and will add line ending characters to the Base64 encoded iv and encrypted data.
You do not want line endings options, by default, no line endings are inserted. Just specify 0
:
NSString *cipherText = [cipherData base64EncodedStringWithOptions:0];
NSString *ivText = [iv base64EncodedStringWithOptions:0];
The option Note that NSUTF8StringEncoding
is not an encoding option for the method base64EncodedStringWithOptions
. The options are:
NSDataBase64Encoding64CharacterLineLength
NSDataBase64Encoding76CharacterLineLength
NSDataBase64EncodingEndLineWithCarriageReturn
NSDataBase64EncodingEndLineWithLineFeed`
which are all line separator options.
My original code contained three errors.
The resulting strings need to be encoded using no parameter as suggested by zaph:
NSString *cipherText = [cipherData base64EncodedStringWithOptions:0]; NSString *ivText = [iv base64EncodedStringWithOptions:0];
To correctly convert the encryption key to NSData
, I use the method provided here and call it like this:
NSData *keyData= [self dataFromHexString:encryptionKey];
The decrypt
function of CryptoJS requires an object like this:
const encrypted = crypto.enc.Base64.parse(message.substring(24)); const params = { ciphertext: encrypted, salt: '' }; const decrypted = crypto.AES.decrypt(params, crypto.enc.Hex.parse(this.encryptionKey.toString()), { iv: iv, padding: crypto.pad.Pkcs7, mode: crypto.mode.CBC }); return decrypted.toString(crypto.enc.Utf8);
Thanks for your help!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.