繁体   English   中英

java 中的 AES-128-CBC 密码

[英]AES-128-CBC cipher in java

我正在尝试使用 AES/128/CBC 实现加密,但我需要使用 64 字节密钥进行加密,但长度有问题。

是否可以使用 64 字节密钥加密 AES/128/CBC,因为我在 php 中使用 64 字节密钥的密码算法并且它可以工作,但在 java 中没有。

这是加密代码:

 public static String ALGORITHM = "AES";

 public static String AES_CBC_PADDING = "AES/CBC/PKCS5Padding";

 public static byte[] encrypt(final byte[] key, final byte[] IV, final byte[] message) throws Exception {
  return AESManager.encryptDecrypt(Cipher.ENCRYPT_MODE, key, IV, message);
 }

 public static byte[] decrypt(final byte[] key, final byte[] IV, final byte[] message) throws Exception {
  return AESManager.encryptDecrypt(Cipher.DECRYPT_MODE, key, IV, message);
 }

 private static byte[] encryptDecrypt(final int mode, final byte[] key, 
                                    final byte[] IV, final byte[] message) throws Exception {
  final Cipher cipher = Cipher.getInstance(AES_CBC_PADDING);
  final SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);
  final IvParameterSpec ivSpec = new IvParameterSpec(IV);
  cipher.init(mode, keySpec, ivSpec);
  return cipher.doFinal(message);
 }

 public static String getHex(byte[] data, int length) {
  StringBuffer sb = new StringBuffer();
  for (int i = 0; i < length; i++) {
   String hexStr = Integer.toHexString(((int) data[i]) & 0xFF);
   if (hexStr.length() < 2) {
    sb.append("0").append(hexStr.toUpperCase());
   } else {
    sb.append(hexStr.toUpperCase());
   }
  }
  return sb.toString();
 }

我有这个错误:

java.security.InvalidKeyException: Invalid AES key length: 64 bytes
at com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87)
at com.sun.crypto.provider.CipherBlockChaining.init(CipherBlockChaining.java:93)
at com.sun.crypto.provider.CipherCore.init(CipherCore.java:591)
at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:346)
at javax.crypto.Cipher.implInit(Cipher.java:805)
at javax.crypto.Cipher.chooseProvider(Cipher.java:863)
at javax.crypto.Cipher.init(Cipher.java:1395)
at javax.crypto.Cipher.init(Cipher.java:1326)
at ec.otecel.tuenti.balance.util.AESManager.encryptDecrypt(AESManager.java)
at ec.otecel.tuenti.balance.util.AESManager.encrypt(AESManager.java)
at ec.otecel.tuenti.balance.util.FreemiumUtil.ciphertoFreemium(FreemiumUtil.java)
at ec.otecel.tuenti.balance.util.FreemiumUtil.main(FreemiumUtil.java)

我有 local_policy.jar 和 US_export_policy.jar 在 C:\Program Files241\jdk1.8.0 这可能是什么问题?

AES-128 需要一个 16 字节的密钥。 “AES-128”中的“128”是以位为单位的密钥大小。 除以 8 得到以字节为单位的密钥大小 == 16 字节。

我在 php 中使用 64 字节密钥的密码算法,它可以工作

我……持怀疑态度。 我怀疑它以某种方式从 64 个字节派生了一个 16 个字节的密钥。

正如@dnault 所述,AES-128 的加密/解密密钥长度为 16 个字节(AES-192 = 24 个字节,AES-256 = 32 个字节)。 您写道,您正在向 PHP 中的解密方法提供 64 个字符的长密钥。 我的示例程序显示只使用了密钥的前 16 个字符。

您的 Java 应用程序的解决方案:只需使用“密钥”的第一个(从左侧看)16 个字节进行加密和解密:

<?php
    // https://stackoverflow.com/questions/62562417/aes-128-cbc-cipher-in-java/62562813#62562813
    $method = "AES-128-CBC";
    $plaintext = "Hello World";
    $key = "1234567890123456789012345678901234567890123456789012345678901234";
    var_dump($key);
    $iv =  "\x08\x07\x05\x06\x04\x01\x02\x03\x12\x11\x0f\x10\x0e\x0b\x0c\x0d";
    $encrypted = base64_encode(openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv));
    echo 'encrypted with key ' . $key . ' is ' . $encrypted . '<br>'. PHP_EOL;
    // truncated key = first 16 characters as for aes-128-cbc
    $key = "1234567890123456";
    var_dump($key);
    $encrypted = base64_encode(openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv));
    echo 'encrypted with key ' . $key . ' is ' . $encrypted . '<br>'. PHP_EOL;
?>

结果:

string(64) "1234567890123456789012345678901234567890123456789012345678901234"
encrypted with key 1234567890123456789012345678901234567890123456789012345678901234 is iLaK2e4sWLOb0KfGy7ZRsQ==<br>
string(16) "1234567890123456"
encrypted with key 1234567890123456                                                 is iLaK2e4sWLOb0KfGy7ZRsQ==<br>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM