不同的AES加密器给我不同的结果...为什么呢?

时间:2018-08-24 16:04:45

标签: ios swift encryption aes

我尝试使用三种不同的库对字符串进行AES加密。

使用工具found here时,我得到以下结果:

Input: "Test" 
key: "MyEncryptionKey1MyEncryptionKey1" (256 Bit)
ECB mode.

这给了我输出Cidor8Ph7pZqPw0x2AwIKw==

但是当我在Swift中使用库时,会得到不同的结果。

使用RNCryptor

当我使用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==

使用AESCrypt

当我使用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中不显示原始字符串中的聊天消息。

2 个答案:

答案 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设置相同的值。然后,您也许可以从所有库中获得相同的结果。