AES 加密未给出预期结果 [英] AES encryption not giving expected result

查看:19
本文介绍了AES 加密未给出预期结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我解密了一个字符串并且它工作正常但是当我尝试加密输出字符串时没有得到相同的结果.

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;
}

电流输出

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

预期输出

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

推荐答案

这个回答无非是把@Topaco的评论写成代码,所以所有的功劳归他所有.

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

请注意我的安全警告 - 将 PBKDF2 迭代次数增加到至少 10000 并且不要使用静态盐.

我更改了一些表示法,以便变量具有它们命名的数据,并且将简短例程更改为通常的行为(获取纯文本,对其进行加密,然后对其进行解密).

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).

输出如预期:

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

完整代码:

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;
    }
}

这篇关于AES 加密未给出预期结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆