I'm generating and exporting a key with CryptoJS:
我正在使用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:
现在我正在尝试使用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:
到目前为止这一切都有效。尝试使用CryptoJS解密数据但是失败了:
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?
问题似乎在于将密钥从CryptoJS传递到iOS。传递给CCCrypt的正确格式是什么?
2 个解决方案
#1
1
The option to base64EncodedStringWithOptions
is incorrect and will add line ending characters to the Base64 encoded iv and encrypted data.
base64EncodedStringWithOptions的选项不正确,并将为Base64编码的iv和加密数据添加行结束字符。
You do not want line endings options, by default, no line endings are inserted. Just specify 0
:
您不需要行结尾选项,默认情况下,不会插入行结尾。只需指定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:
选项请注意,NSUTF8StringEncoding不是方法base64EncodedStringWithOptions的编码选项。选项是:
NSDataBase64Encoding64CharacterLineLength
NSDataBase64Encoding76CharacterLineLength
NSDataBase64EncodingEndLineWithCarriageReturn
NSDataBase64EncodingEndLineWithLineFeed`
which are all line separator options.
这些都是行分隔符选项。
#2
0
My original code contained three errors.
我的原始代码包含三个错误。
-
The resulting strings need to be encoded using no parameter as suggested by zaph:
生成的字符串需要使用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,我使用此处提供的方法并将其调用如下:
NSData *keyData= [self dataFromHexString:encryptionKey];
-
The
decrypt
function of CryptoJS requires an object like this:CryptoJS的解密函数需要这样的对象:
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!
谢谢你的帮助!
#1
1
The option to base64EncodedStringWithOptions
is incorrect and will add line ending characters to the Base64 encoded iv and encrypted data.
base64EncodedStringWithOptions的选项不正确,并将为Base64编码的iv和加密数据添加行结束字符。
You do not want line endings options, by default, no line endings are inserted. Just specify 0
:
您不需要行结尾选项,默认情况下,不会插入行结尾。只需指定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:
选项请注意,NSUTF8StringEncoding不是方法base64EncodedStringWithOptions的编码选项。选项是:
NSDataBase64Encoding64CharacterLineLength
NSDataBase64Encoding76CharacterLineLength
NSDataBase64EncodingEndLineWithCarriageReturn
NSDataBase64EncodingEndLineWithLineFeed`
which are all line separator options.
这些都是行分隔符选项。
#2
0
My original code contained three errors.
我的原始代码包含三个错误。
-
The resulting strings need to be encoded using no parameter as suggested by zaph:
生成的字符串需要使用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,我使用此处提供的方法并将其调用如下:
NSData *keyData= [self dataFromHexString:encryptionKey];
-
The
decrypt
function of CryptoJS requires an object like this:CryptoJS的解密函数需要这样的对象:
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!
谢谢你的帮助!