【问题标题】:Problems encoding/decoding using AES-128-CBC使用 AES-128-CBC 编码/解码的问题
【发布时间】:2011-11-30 17:35:40
【问题描述】:

所以基本上我有这些 sn-ps 的代码,并希望它们产生相同的输出:

require 'openssl'
aes = OpenSSL::Cipher::Cipher.new("AES-128-CBC")
aes.key = "aaaaaaaaaaaaaaaa"
aes.iv = "aaaaaaaaaaaaaaaa"
aes.encrypt
encrypted = aes.update("1234567890123456") << aes.final
puts encrypted.unpack('H*').join

打印出来:

8d3bbffade308f8e4e80cb77ecb8df19ee933f75438cec1315c4a491bd1b83f4

还有这段 Java 代码:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
String key = "aaaaaaaaaaaaaaaa";
String textToEncryptpt = "1234567890123456";

SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(key.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(textToEncryptpt.getBytes());
System.out.println(Crypto.bytesToHex(encrypted));

打印:

2d3760f53b8b3dee722aed83224f418f9dd70e089ecfe9dc689147cfe0927ddb

令人烦恼的是几天前它还在工作......所以我不确定发生了什么。这段代码有什么问题?有什么不寻常的地方吗?

【问题讨论】:

  • 你应该在设置密钥或iv之前调用#encrypt

标签: java ruby aes


【解决方案1】:

Ruby 脚本错误。你得先调用encrypt方法,然后设置keyiv

require 'openssl'
aes = OpenSSL::Cipher::Cipher.new("AES-128-CBC")
aes.encrypt
aes.key = "aaaaaaaaaaaaaaaa"
aes.iv = "aaaaaaaaaaaaaaaa"
encrypted = aes.update("1234567890123456") << aes.final
puts encrypted.unpack('H*').join

我发现是因为在尝试解码加密字符串时,我得到了:

aescrypt.rb:13:in `final': bad decrypt (OpenSSL::Cipher::CipherError)
    from aescrypt.rb:13:in `<main>'

【讨论】:

    【解决方案2】:

    您似乎已经找到了脚本给出不同结果的原因。

    还有一些需要考虑的事情:

    • 永远不要对程序中的密钥进行硬编码 - 这样您就无法轻易更改它,而且如果有人可以访问您的程序代码,她也可以看到密钥。
    • 永远不要使用常量初始化向量。相反,生成一个随机的并与密文一起发送。或者,如果您从密码和一些盐生成密钥,您也可以从相同的...生成 IV,但不要直接将密钥用作 IV。
    • 您的键/IV 值是字符串,而不是字节。 String.getBytes()(在 Java 中)使用某种编码将字符串转换为字节。使用的编码是系统相关的,通常的字符串编码(UTF-8、Latin-1、...)都不能将所有字节表示为可打印(和可输入)字符。如果您必须将密钥存储为字符串,最好使用 Base64 或十六进制编码。
    • 每当您将字符串转换为字节时,请指定一种编码(稍后使用相同的编码进行检索)。

    【讨论】:

    • 你能稍微解释一下关于随机生成 IV 的事情吗?我的意思是...我必须对服务器中的文本进行加密,然后从 Android 应用程序中对其进行解密...如果我随机生成 IV,应用程序如何知道使用了什么 IV?
    • 如果您在服务器中随机生成 IV,那么您必须将其与您的数据一起发送。 (发送它没有安全风险,只要在您的数据已知之前不发送。)
    【解决方案3】:

    @Cristian,对于键和初始向量,您可以使用今天的日期加上安全的固定关键字来创建一个函数。

    例如:键 = 2012 年 1 月 8 日 + 键

    对于初始向量,

    例如:iv = 2012 年 1 月 8 日 + IV

    然后将该数据(密钥和 iv)输入到 MD5 中,它将生成可用于密钥和 IV 的 16 个字节的输出。每天key和iv都会随机变化。

    确保两个系统使用相同的日期格式并在同一日期设置。

    【讨论】:

      猜你喜欢
      • 2020-10-06
      • 2015-11-04
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      • 2018-04-04
      • 2017-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多