在我们的Angular项目中,我们需要解密由iOS加密的文本/文件。
iOS团队正在使用带有ECB模式算法的AES 128位加密。
我尝试使用CryptoJS,aes-js并直接使用NodeJs中的Crypto类。
来自iOS的加密文本或解密的UTF8字符串的结果不匹配。我们获得了不同的价值。
iOS团队正在使用aes-commoncrypto库
在调用通用密码库之前,我们将字符串转换为iOS数据(Dataatype),即字节缓冲区并使用UTF8进行编码
加密-
let fileUrl = URL(fileURLWithPath: folderPath)
try? Utils.aes128Encryption(forData:
textAnnotationText.data(using: .utf8))?.write(to: fileUrl)
解密-
let _fileURL = documentsDirectory.appendingPathComponent( path)
do {
if let decryptedData = Utils.aes128Decryption(forData: try Data(contentsOf: _fileURL)) {
message = String(decoding: decryptedData, as: UTF8.self)
}
}
CCCrypt(operation,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr,
kCCBlockSizeAES128,
ivPtr,
[self bytes],
dataLength,
buffer,
bufferSize,
&numBytesEncrypted)
根据对以上代码的理解,iOS团队正在使用ECB模式算法。 输出:UTF8字符串,我们将其写入文档目录文件。
解决方案1: 使用CryptoJS:
let key = CryptoJS.enc.Utf8.parse(TESTKEY);
let iv = CryptoJS.lib.WordArray.create([0, 0]);
const encrypted = CryptoJS.AES.encrypt(message, key, {
keysize: 256 / 8,
iv: iv.toString(),
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
const crypto64 = crypto.ciphertext.toString();
输出:Base64编码的字符串。 (与iOS加密文本不匹配)
解决方案2:使用AES Js:
let aesEcb = new aesjs.ModeOfOperation.ecb(Buffer.from(key, 'utf8'));
let textBytes = aesjs.utils.utf8.toBytes(str);
let encryptedBytes = aesEcb.encrypt(textBytes);
输出:我们收到错误消息“无效的纯文本大小(必须为16字节的倍数)”
解决方案3:使用加密解密器
fs.readFile('./sample_text.html', 'utf-8', function (err, data) {
if (err) throw err;
console.log(data);
const d = crypto.createDecipheriv('aes-128-ecb', convertCryptKey(key), '')
let ret = ''
d.setAutoPadding(false);
console.log(Buffer.from(data, 'utf8'));
ret = d.update(data, 'binary', 'utf8')
console.log(ret);
decoded = Buffer.concat([ ret, d.final() ]);
console.log(decoded);
});
function convertCryptKey(strKey) {
const newKey = new Buffer([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
strKey = new Buffer(strKey)
for (let i = 0; i < strKey.length; i++) newKey[i % 16] ^= strKey[i]
return newKey
}
输出:与iOS加密的字符串或文件不匹配