我尝试使用三种不同的库对字符串进行AES加密。
使用工具found here时,我得到以下结果:
Input: "Test"
key: "MyEncryptionKey1MyEncryptionKey1" (256 Bit)
ECB mode.
这给了我输出Cidor8Ph7pZqPw0x2AwIKw==
但是当我在Swift中使用库时,会得到不同的结果。
当我使用RNcryptor时,我在使用以下代码:
class func encryptMessage(message: String) throws -> String {
guard let messageData = message.data(using: .utf8) else { return message }
let cipherData = RNCryptor.encrypt(data: messageData, withPassword: key)
return cipherData.base64EncodedString()
}
输出:
AwF8a+HziYkO4iHdcI3jY8p9QAY461DVgkjkYUFMkuh4A2a8FCfa4RgS9Z37QhJGxIL0Q20RE3BL4nmLQVFOfZmBpj8l0wj9YZgqZmrkxRFYQQ==
当我使用RNcryptor时,我在使用以下代码:
class func encryptMessageAES(message: String) -> String{
guard let encryptedData = AESCrypt.encrypt(message, password: key) else { return message }
return encryptedData
}
输出:
T5/mR8UT/EXeUobPTLhcFA==
如果我使用的是CryptoSwift
,我也会得到第三个结果。我使用Android的同事总是会得到相同的结果-与网络工具匹配。
我对加密完全陌生,我发现自己做错了什么。但是我无法真正意识到。我还应该提到,对于那些有权访问数据库的用户,此加密仅用于在Firebase中不显示原始字符串中的聊天消息。
答案 0 :(得分:2)
AES 的定义非常精确,当事情在不同的实现之间无法正常工作时,通常是由于在AES之上构建了各种事物。 AES算法本身始终对二进制数据进行操作。您加密的数据必须是二进制的。用于加密的密钥必须为二进制,如果正在使用IV,则还必须为二进制。
在所有向实施例提供非二进制数据的实施中,已经选择了如何将该数据转换为可以与 AES 一起使用的格式。有时,这些转换只是简单的数据转换,例如十六进制或base64解码,而其他时候,新概念正在发挥作用,例如从密码派生加密密钥。
您的所有三个示例均使用文本作为Key的输入,并且每个实现都在如何支持该文本方面做出了一些选择。
您链接到的第一页,已选择仅将ASCII字符串解释为二进制密钥。这是一个[可怕的选择],因为它(除了与其他所有功能都不兼容)有效地消除了密钥的每个字节1-2位,从而大大降低了强度。
在 RNCryptor 示例中,您用withPassword: key
指定密钥。在这里,RNCryptor团队选择使用 PBKDF2 密钥派生功能来制作实际的 AES 密钥。这解决了一个不同的用例,在该用例中,您有一个可能需要使用stretching进行加密的安全周密码。如果您有实际的钥匙,那是不可行的。
对于 AESCrypt ,您似乎还提供了密码作为输入。尚不清楚如何将其转换为实际密钥。
答案 1 :(得分:0)
您还必须在AES中设置另一个值iv
。因此,请尝试在所有三个库中找到该iv
。并且尝试为iv
设置相同的值。然后,您也许可以从所有库中获得相同的结果。