我有一个要求,使用 Dart 从 flutter web 应用程序加密字符串。加密的字符串发送到服务器,iOS Swift 将使用该字符串。
Dart 文件
String encryptString(Uint8List key) {
try {
final encryptionKey = Key(key);
final iv = IV.fromLength(16); // 16 bytes IV for AES-GCM
final macValue = utf8.encode("");
final encrypter = Encrypter(AES(encryptionKey, mode: AESMode.gcm));
final encrypted = encrypter.encrypt(
this,
iv: iv,
associatedData: macValue,
);
final concatenatedBytes = Uint8List.fromList([...iv.bytes, ...encrypted.bytes, ...macValue]);
final base64Encoded = base64.encode(concatenatedBytes);
return base64Encoded;
} catch (e) {
print('Error while encrypting: $e');
return '';
}
}
但是,我无法在 Swift 中解密加密文本。我总是收到 CryptoKit.CryptoKitError.authenticationFailure
快速代码
func decrypt(withKey key: SymmetricKey) throws -> String {
guard let encryptedData = Data(base64Encoded: self) else { throw EncryptionError.invalidData }
// Open the sealed box using the encryption key
do {
let sealedBox = try AES.GCM.SealedBox(combined: encryptedData)
// Decrypt the data
let decryptedData = try AES.GCM.open(sealedBox, using: key)
// Convert decrypted data to string
guard let decryptedString = String(data: decryptedData, encoding: .utf8) else {
throw EncryptionError.decryptionFailed
}
return decryptedString
} catch {
print(error.localizedDescription)
throw EncryptionError.invalidData
}
}
我尝试了上面的片段。好像不行,请帮忙:(
密码方案彼此不兼容。您在 Dart 上使用默认的“SIC”方案(计数器模式下的 AES),然后尝试在 Swift 中使用另一种名为 GCM 的方案进行解密。这显然行不通,而且 Dart 库似乎不支持经过身份验证的密码,例如 GCM。这些都是必需的,否则您很容易受到明文预言机攻击,并且没有消息完整性或身份验证(正如您可能想象的那样,这很糟糕)。
您可以尝试 Dart 的“加密”库中包含的 Fernet。它至少添加了一个用于身份验证的 HMAC 标签,这基本上使其成为经过身份验证的密码。快速浏览一下,发现这个答案包含 swift 代码。
请注意,这不是针对 Dart 或 Swift 代码的建议;我没有以任何方式对其进行代码审查。但如果没有任何加密知识,你可能会比使用 NaCL、Fernet 等“密封盒”更糟糕。很久以前,我确实对 Fernet 进行了协议审查,这是值得的。
Dart 库引发了很多危险信号。它的得分很高,但它没有正式列出任何规格,而且似乎没有注意到 AES-SIC 和 AES-CTR 实际上是相同的模式,这表明作者和社区可能相当缺乏经验。