我使用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();
现在我尝试使用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]
到目前为止这一切都有效。然而,尝试使用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))
问题似乎在于将密钥从CryptoJS传递到iOS。传递给CCCrypt的正确格式是什么?
答案 0 :(得分:1)
base64EncodedStringWithOptions
的选项不正确,会将行结尾字符添加到Base64编码的iv和加密数据中。
您不需要行结尾选项,默认情况下,不会插入行结尾。只需指定0
:
NSString *cipherText = [cipherData base64EncodedStringWithOptions:0];
NSString *ivText = [iv base64EncodedStringWithOptions:0];
选项请注意,NSUTF8StringEncoding
不是方法base64EncodedStringWithOptions
的编码选项。选项包括:
NSDataBase64Encoding64CharacterLineLength
NSDataBase64Encoding76CharacterLineLength
NSDataBase64EncodingEndLineWithCarriageReturn
NSDataBase64EncodingEndLineWithLineFeed`
这些都是行分隔符选项。
答案 1 :(得分:0)
我的原始代码包含三个错误。
生成的字符串需要使用zaph:
建议的无参数进行编码NSString *cipherText = [cipherData base64EncodedStringWithOptions:0];
NSString *ivText = [iv base64EncodedStringWithOptions:0];
要将加密密钥正确转换为NSData
,我使用here提供的方法并将其称为:
NSData *keyData= [self dataFromHexString:encryptionKey];
CryptoJS的decrypt
函数需要这样的对象:
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);
感谢您的帮助!