【问题标题】:AES256 on Java vs PHPJava 与 PHP 上的 AES256
【发布时间】:2013-01-28 12:36:25
【问题描述】:

到目前为止一直在逃避我的快速(漫长的夜晚)。我正在比较 PHP 与 Java 中的 AES256 并注意到差异。为简单起见,请忽略 ascii 键和 null IV,它们将在生产中被替换。但我需要先克服这个问题,但我不知道我错在哪里:

PHP:

echo base64_encode(
    mcrypt_encrypt(
        MCRYPT_RIJNDAEL_128,
        "1234567890ABCDEF1234567890ABCDEF",
        "This is a test",
        MCRYPT_MODE_CBC,
        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    )
);

Java

byte[] key = "1234567890ABCDEF1234567890ABCDEF".getBytes("UTF-8");
byte[] iv  = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
SecretKeySpec newKey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
byte[] results = cipher.doFinal("This is a test".getBytes("UTF-8"));

return Base64.encodeToString(results,Base64.DEFAULT);

PHP 输出:0KwK+eubMErzDaPU1+mwTQ==

Java 输出:DEKGJDo3JPtk48tPgCVN3Q==

不完全是我所期待的 o_O !

我也尝试过MCRYPT_MODE_CBCMCRYPT_MODE_CFBMCRYPT_MODE_ECBMCRYPT_MODE_NOFB 等。它们都没有生成 Java 字符串。

【问题讨论】:

  • 你试过把Cipher.getInstance("AES");改成Cipher.getInstance("AES/CBC/NoPadding");
  • Yezzir, "AES/CBC/NoPadding" 产生 IllegalBlockSizeException:数据未对齐块大小。 “AES/CBC/PKCS5Padding”产生“DEKGJDo3JPtk48tPgCVN3Q==”,“AES/CBC/PKCS7Padding”也是如此。
  • 这对我来说太愚蠢了,如果没有填充,您必须确保您提供的是块大小的倍数。我将发布一个我认为是解决方案的答案。

标签: java php encryption aes


【解决方案1】:

PHP 用\0 填充输入字节,使其成为块大小的倍数。 Java 中的等价物是这样的(假设您要加密的字符串在 data 中):

Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
int blockSize = cipher.getBlockSize();

byte[] inputBytes = data.getBytes();
int byteLength = inputBytes.length;
if (byteLength % blockSize != 0) {
    byteLength = byteLength + (blockSize - (byteLength % blockSize));
}

byte[] paddedBytes = new byte[byteLength];

System.arraycopy(inputBytes, 0, paddedBytes, 0, inputBytes.length);

cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
byte[] results = cipher.doFinal(paddedBytes);

作为对此的警告 - 不需要从零开始的填充。无法确定字符串末尾的 \0 字符与实际填充之间的区别。最好改用 PKCS5Padding,但在 PHP 中会得到不同的结果。问问自己是否需要像这样的跨平台加密。

【讨论】:

  • 这不是您要找的吗?从头开始 - 没有看到接受的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-10
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多