AES encryption not giving expected result

南笙酒味 提交于 2020-12-15 05:38:07

问题


I have decrypted a string and it works properly but when I am trying to encrypt the output string not getting the same result.

public static void main(String[] args) {
  // TODO Auto-generated method stub


  String cipherstring = "9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=";
  byte[] cipherByte = Base64.getDecoder().decode(cipherstring);
  String cum006333 = decrypt(cipherstring, "KEY@CRISIL123");
  System.out.println("decrpted output:  " + cum006333);
  String enc = encrypt(cum006333, "KEY@CRISIL123");
  System.out.println("encrpted output:  " + enc);

}

public static String decrypt(String cipherText, String passphrase) {
  String s = null;
  try {
    System.out.println("decrpted input :  " + cipherText);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    byte[] bytes = Base64.getDecoder().decode(cipherText);
    int keySize = 256;
    int iterCount = 1000;
    int ivLength = 16;
    byte[] saltByte = new byte[] {
      0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
    };
    // KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), saltByte, iterCount, (keySize + (8 * ivLength))); // 32 + 16
    KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), saltByte, iterCount, (keySize + 128)); // 32 + 16
    byte[] rawKey = factory.generateSecret(spec).getEncoded(); // 48 bytes
    byte[] keyDerived = Arrays.copyOf(rawKey, (keySize / 8)); // first 32 bytes
    byte[] ivB = Arrays.copyOfRange(rawKey, (keySize / 8), rawKey.length); // last 16 bytes
    SecretKey key = new SecretKeySpec(keyDerived, "AES");
    IvParameterSpec iv = new IvParameterSpec(ivB);
    cipher.init(Cipher.DECRYPT_MODE, key, iv);
    //byte[] original = cipher.doFinal(data);
    byte[] original = cipher.doFinal(bytes);
    s = new String(original, StandardCharsets.UTF_16LE);


  } catch (Exception ex) {
    ex.printStackTrace();
  }
  return s;
}
public static String encrypt(String cipherText, String passphrase) {
  String s = null;
  try {
    System.out.println("encrypted input :  " + cipherText);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    // byte[] bytes = Base64.getDecoder().decode(cipherText);
    cipherText = new String(cipherText.getBytes(), StandardCharsets.UTF_16LE);
    int keySize = 256;
    int iterCount = 1000;
    int ivLength = 16;
    byte[] saltByte = new byte[] {
      0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
    };
    KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), saltByte, iterCount, (keySize + (8 * ivLength))); // 32 + 16
    // KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), saltByte, iterCount, (keySize + 128)); // 32 + 16
    byte[] rawKey = factory.generateSecret(spec).getEncoded(); // 48 bytes
    byte[] keyDerived = Arrays.copyOf(rawKey, (keySize / 8)); // first 32 bytes
    byte[] ivB = Arrays.copyOfRange(rawKey, (keySize / 8), rawKey.length); // last 16 bytes
    SecretKey key = new SecretKeySpec(keyDerived, "AES");
    IvParameterSpec iv = new IvParameterSpec(ivB);
    cipher.init(Cipher.ENCRYPT_MODE, key, iv);
    //byte[] original = cipher.doFinal(data);
    byte[] original = cipher.doFinal(cipherText.getBytes());

    s = Base64.getEncoder().encodeToString(original);
    //s = new String(original, StandardCharsets.UTF_16LE);
  } catch (Exception ex) {
    ex.printStackTrace();
  }
  return s;
}

current output

decrpted input :  9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrpted output:  CUM006333
encrypted input :  CUM006333
encrpted output:  YVhOFyq9PAOkegIFDR/Ojw==

expected output

decrpted input :  9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrpted output:  CUM006333
encrypted input :  CUM006333
encrpted output:  9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=

回答1:


This answer is nothing more than taking the comment from @Topaco into code, so all credits belong to him.

Kindly note my security warnings - increase the PBKDF2 iterations to a minimum of 10000 and do not use a static salt.

I changed some denotations so the variables have the data they are naming and the short routine is changed to a usual behavior (taking a plainText, encrypt it and then decrypt it).

The output is like expected:

plaintext input :  CUM006333
encrypted output:  9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrypted input :  9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrypted output:  CUM006333

full code:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;

public class MainSo {
    public static void main(String[] args) {
        // https://stackoverflow.com/questions/64386104/aes-encryption-not-giving-expected-result
        String plainText = "CUM006333";
        String passphrase = "KEY@CRISIL123";
        String enc = encrypt(plainText, passphrase);
        System.out.println("encrypted output:  " + enc);
        String dec = decrypt(enc, passphrase);
        System.out.println("decrypted output:  " + dec);
    }

    public static String decrypt(String cipherText, String passphrase) {
        String s = null;
        try {
            System.out.println("decrypted input :  " + cipherText);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            byte[] bytes = Base64.getDecoder().decode(cipherText);
            int keySize = 256;
            // ### SECURITY WARNING - use minimum 10000 iterations ###
            int iterCount = 1000;
            int ivLength = 16;
            // ### SECURITY WARNING - don't use a static salt
            byte[] saltByte = new byte[] {
                    0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
            };
            KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), saltByte, iterCount, (keySize + 128)); // 32 + 16
            byte[] rawKey = factory.generateSecret(spec).getEncoded(); // 48 bytes
            byte[] keyDerived = Arrays.copyOf(rawKey, (keySize / 8)); // first 32 bytes
            byte[] ivB = Arrays.copyOfRange(rawKey, (keySize / 8), rawKey.length); // last 16 bytes
            SecretKey key = new SecretKeySpec(keyDerived, "AES");
            IvParameterSpec iv = new IvParameterSpec(ivB);
            cipher.init(Cipher.DECRYPT_MODE, key, iv);
            //byte[] original = cipher.doFinal(data);
            byte[] original = cipher.doFinal(bytes);
            s = new String(original, StandardCharsets.UTF_16LE);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return s;
    }
    public static String encrypt(String plainText, String passphrase) {
        String s = null;
        try {
            System.out.println("plaintext input :  " + plainText);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            // byte[] bytes = Base64.getDecoder().decode(cipherText);
            //cipherText = new String(cipherText.getBytes(), StandardCharsets.UTF_16LE);
            int keySize = 256;
            // ### SECURITY WARNING - use minimum 10000 iterations ###
            int iterCount = 1000;
            int ivLength = 16;
            // ### SECURITY WARNING - don't use a static salt
            byte[] saltByte = new byte[] {
                    0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
            };
            KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), saltByte, iterCount, (keySize + (8 * ivLength))); // 32 + 16
            // KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), saltByte, iterCount, (keySize + 128)); // 32 + 16
            byte[] rawKey = factory.generateSecret(spec).getEncoded(); // 48 bytes
            byte[] keyDerived = Arrays.copyOf(rawKey, (keySize / 8)); // first 32 bytes
            byte[] ivB = Arrays.copyOfRange(rawKey, (keySize / 8), rawKey.length); // last 16 bytes
            SecretKey key = new SecretKeySpec(keyDerived, "AES");
            IvParameterSpec iv = new IvParameterSpec(ivB);
            cipher.init(Cipher.ENCRYPT_MODE, key, iv);
            //byte[] original = cipher.doFinal(data);
            byte[] cipherText = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_16LE));
            //byte[] original = cipher.doFinal(cipherText.getBytes());
            s = Base64.getEncoder().encodeToString(cipherText);
            //s = new String(original, StandardCharsets.UTF_16LE);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return s;
    }
}


来源:https://stackoverflow.com/questions/64386104/aes-encryption-not-giving-expected-result

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!