使用AES-128-CBC编码/解码的问题

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

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 

令人讨厌的是,它几天前正在工作……所以我不确定发生了什么。 这段代码出了什么问题? 你看到什么exception吗?

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 `
'

好像你发现你的脚本确实给出了不同的结果。

还有一些事情需要考虑:

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

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

例如:key = 2012年1月8日+密钥

对于初始矢量,

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

然后将该数据(键和iv)输入到MD5,它将产生输出16个字节,您可以将其用于Key和IV。 每天,钥匙和静脉注射会随机变化。

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