簡體   English   中英

如何解密Java中的aes-256-cbc

[英]How to decrypt aes-256-cbc in Java

我在php加密了字符串,從php和node.js解密成功,另外還要通過java解密。

幫我舉個從 java 解密的例子?

PHP 加密密碼

/* encrypt */
$encryption_method = 'aes-256-cbc';
$secretHash = "d95acd54c6a821ff32c52825b931c194";
$iv_size = openssl_cipher_iv_length($encryption_method);
$iv = openssl_random_pseudo_bytes($iv_size);

//encrypt
$encryptedMessage = openssl_encrypt($new_token, $encryption_method, $secretHash, 0, $iv);

//Concatenate iv with data
$ciphertext = bin2hex($iv).$encryptedMessage;

/* decrypt the cipher */
$iv_size = openssl_cipher_iv_length($encryptionMethod);
$iv = hex2bin(substr($encryptedMessageWithIv, 0, $iv_size * 2));

$decryptedMessage = openssl_decrypt(substr($encryptedMessageWithIv, $iv_size * 2), $encryptionMethod, $secretHash, 0, $iv);

以下是使用AES算法對字符串進行加密和解密的過程。

 private static final String key = "aesEncryptionKey";
    private static final String initVector = "encryptionIntVec";

    public static String encrypt(String value) {
        try {
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] encrypted = cipher.doFinal(value.getBytes());
            return Base64.encodeBase64String(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

public static String decrypt(String encrypted) {
    try {
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));

        return new String(original);
    } catch (Exception ex) {
        ex.printStackTrace();
    }

    return null;
}

如果不知道初始化向量,請嘗試使用下面的代碼段。

public byte[] decrypt(String encryptedString) throws DataLengthException, InvalidCipherTextException {

        byte[] input = encryptedString.getBytes("UTF-8");
        CBCBlockCipher cbcBlockCipher = new CBCBlockCipher(new AESEngine());
        SecureRandom random = new SecureRandom();;
        KeyParameter key = new KeyParameter("$secretHash".getBytes());// your key string
        BlockCipherPadding blockCipherPadding = new PKCS7Padding();;
        PaddedBufferedBlockCipher pbbc = new PaddedBufferedBlockCipher(cbcBlockCipher, blockCipherPadding);

        int blockSize = cbcBlockCipher.getBlockSize(); // Make sure this block size is same as that used while encrypting the string.
        int inputOffset = 0;
        int inputLength = input.length;
        int outputOffset = 0;

        byte[] initializationVector = new byte[blockSize];

        System.arraycopy(input, 0, initializationVector, 0, blockSize);
        inputOffset += blockSize;
        inputLength -= blockSize;

        pbbc.init(encrypt, new ParametersWithIV(key, initializationVector));
        byte[] output = new byte[pbbc.getOutputSize(inputLength) + outputOffset];

        int outputLength = outputOffset + pbbc.processBytes(input, inputOffset, inputLength, output, outputOffset);

        outputLength += pbbc.doFinal(output, outputLength);

        return Arrays.copyOf(output, outputLength);
    }

以防萬一它對將來的人有幫助:使用 AES/CBC/PKCS5PADDING 加密以及生成附加到 Java 中最終密文的動態 IV 可以通過以下代碼完成:

加密(JAVA)

public String encryptPlainText(String plainText) {
      String cipherText = "";
      try {
           String keyString = "examplesecretkeyexamplesecretkey";

           //Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy
           Security.setProperty("crypto.policy", "unlimited");

           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
           SecretKeySpec keyspec = new SecretKeySpec(keyString.getBytes(), "AES");

           byte[] v = new byte[16];
           new SecureRandom().nextBytes(v);
           IvParameterSpec iv = new IvParameterSpec(v);

           cipher.init(Cipher.ENCRYPT_MODE, keyspec, iv);
           byte[] cipherTextByteArray = cipher.doFinal(plainText.getBytes());

           //appending iv to ciphertext without any additional libraries to handle the concatenation of the two byte arrays
           byte[] ivWithCipherTextByteArray = new byte[v.length + cipherTextByteArray.length];
           System.arraycopy(v, 0, ivWithCipherTextByteArray, 0, v.length);
           System.arraycopy(cipherTextByteArray, 0, ivWithCipherTextByteArray, v.length, cipherTextByteArray.length);

           cipherText = new String(Base64.getEncoder().encode(ivWithCipherTextByteArray));
      } catch (Exception e) {
           LOG.info("Exception", e);
      }

      return cipherText;
 }

對上述代碼得到的cipherText進行解密可以通過以下方式實現:

解密(JAVA)

public static String decryptCipherText(String cipherText) {
      String plainText="";
      try {
           String keyString = "examplesecretkeyexamplesecretkey";

           Security.setProperty("crypto.policy", "unlimited");

           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
           SecretKeySpec keyspec = new SecretKeySpec(keyString.getBytes(), "AES");

           byte[] cipherTextByteArray = Base64.getDecoder().decode(cipherText);

           //initialize the IvParameterSpec with the first 16 bytes of the cipherText
           IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(cipherTextByteArray, 0, 16));

           //cipherText to decrypt is now the original one with the first 16 bytes removed (the IV used above)
           cipherTextByteArray = Arrays.copyOfRange(cipherTextByteArray, 16, cipherTextByteArray.length);

           cipher.init(Cipher.DECRYPT_MODE, keyspec, iv);
           plainText = new String(cipher.doFinal(cipherTextByteArray));
      } catch (Exception e) {
           LOG.info("Exception", e);
      }

      return plainText;
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM