【问题标题】:Decrypt using AES-256-ECB in Java在 Java 中使用 AES-256-ECB 解密
【发布时间】:2021-01-19 22:13:14
【问题描述】:

我在 PHP 中使用 AES-256-ECB 加密了字符串。

$sString   = "test"
$sEncryptionMethod = "AES-256-ECB";
$sEncryptionKey = "mysecretkey";

openssl_encrypt($sString, $sEncryptionMethod, $sEncryptionKey)

我想用 Java/Scala 解密它吗?

 String secret = "mysecretkey";
 SecretKeySpec skeySpec = new SecretKeySpec(encKey.getBytes("UTF-8"), "AES");
 byte[] decodedValue = Base64.getDecoder.decode(token);

 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
 int decryptMode = Cipher.DECRYPT_MODE;
 cipher.init(decryptMode, skeySpec);
 new String(cipher.doFinal(decodedValue));

我看到以下错误?我们如何使用 Java 解密相同的内容? 注意:(PHP 中的解密按预期工作)但我想在 Java 中执行此操作

Given final block not properly padded. Such issues can arise if a bad key is used during decryption.

【问题讨论】:

标签: java php encryption aes


【解决方案1】:

密钥的长度必须正好为 256 位。显然,PHP 方面正在对"mysecretkey" 执行一些未指定的魔法巫术以获取 256 位密钥。 Java 通常不会像 PHP 那样参与“用户似乎不知道他们在做什么,嗯,我会在黑暗中冒险”,这就是这里的问题。

弄清楚“mysecretkey”是如何变成 256 位密钥的,并在 java 中复制。

注意:欧洲央行是extremely insecure。听起来您对加密的了解还不够,没有希望生成一个实际上很难轻易破解的应用程序。

NB2:请注意,PHP 文档本身强烈建议“密钥”应该是某种 256 位的加密派生安全源。 openssl_encrypt 在您提供损坏的钥匙时实际上会给您一个答案,这一事实有点令人侧目。请参阅PHP manual on openssl_encrypt 上的各种 cmets,它们清楚地突出了那里正在发生的一些奇怪现象,但没有一个足够清楚以实际解释 PHP 正在 在这里做什么。

【讨论】:

  • 感谢您的解释,我对 PHP 了解不多,我尝试解码,因为原始加密是在 PHP 端完成的。
  • 你不能把这归咎于 PHP。 It's openssl that pads the key with zeros。我想 openssl 扩展的作者错过了为一个很难正确使用的库提供一个健全的 API 的机会,但仍然如此。
  • “PHP 端正在做一些未指定的魔法巫术” - PHP 没有做任何魔法,只是用(十六进制)x00 将密钥填充到所需的长度。使用 AES-256 时,OPENSSL 需要 256/8 = 32 字节长度的密钥。由于“mysecretkey”是 11 字节长,只需将 32-11 = 21 x00's 添加到 Java 端的密钥中,解密将起作用。 安全警告 不要使用 UNSECURE ECB 模式。
  • @MichaelFehr - 是的,但是用 0 值填充(就像切断太长的键一样)是某种魔法(虽然很简单):无效的键是 静默 使用任意规则转换为有效密钥。
  • 那么补救方法就是简单地使用$sEncryptionKey = "mysecretkey\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",使其长度为32字节?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 2012-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多