我有一个Json字符串
String message = "{\"version\":\"1.0\",\"rccCubeType\":\"TCR_CASE_D\",\"timeZone\":\"Asia/Kolkata\",\"timeOffset\":\"+05:30\",\"tenant\":\"0001\",\"extractionTime\":\"20170713162718117\"}";
我正在使用
加密此字符串 import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.KeySpec;
public class AESEncrypter {
private static final Logger LOGGER = Logger.getLogger(AESEncrypter.class);
private static final byte[] SALT = {
(byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
(byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03
};
private static final int ITERATION_COUNT = 65536;
private static final int KEY_LENGTH = 256;
private Cipher ecipher;
private Cipher dcipher;
public AESEncrypter(String passPhrase) {
SecretKeyFactory factory = null;
Field field = null;
try {
// hack for JCE unlimited strength policy jar installations
field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, false);
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), SALT, ITERATION_COUNT, KEY_LENGTH);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
ecipher.init(Cipher.ENCRYPT_MODE, secret);
dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = ecipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
dcipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
LOGGER.error("Invalid Key Exception",e);
} catch (InvalidAlgorithmParameterException e) {
LOGGER.error("Invalid Algorithm Parameter Exception",e);
} catch (NoSuchPaddingException e) {
LOGGER.error("No Such Padding Exception",e);
} catch (InvalidParameterSpecException e) {
LOGGER.error("Invalid Parameter Exception",e);
} catch (InvalidKeySpecException e) {
LOGGER.error("Invalid Key Spec Exception",e);
} catch (NoSuchFieldException e) {
LOGGER.error("No Such field Exception",e);
} catch (ClassNotFoundException e) {
LOGGER.error("Class Not Found Exception",e);
} catch (IllegalAccessException e) {
LOGGER.error("Illegal Argument Exception",e);
}
}
public String encrypt(String encrypt) {
byte[] bytes = new byte[0];
byte[] encrypted = new byte[0];
try {
bytes = encrypt.getBytes("UTF-8");
encrypted = encrypt(bytes);
} catch (Exception e) {
LOGGER.error("Exception",e);
}
return Base64.encodeBase64String(encrypted);
}
private byte[] encrypt(byte[] plain) {
try {
return ecipher.doFinal(plain);
} catch (IllegalBlockSizeException e) {
LOGGER.error("Illegal Block Size Exception",e);
} catch (BadPaddingException e) {
LOGGER.error("Bad Padding Exception",e);
}
return null;
}
public String decrypt(String encrypt) throws UnsupportedEncodingException {
byte[] bytes = Base64.decodeBase64(encrypt.getBytes("UTF-8"));
byte[] decrypted = decrypt(bytes);
return new String(decrypted);
}
public byte[] decrypt(byte[] encrypt) {
try {
return dcipher.doFinal(encrypt);
} catch (IllegalBlockSizeException e) {
LOGGER.error("Illegal Block Size Exception",e);
} catch (BadPaddingException e) {
LOGGER.error("Bad Padding Exception",e);
}
return null;
}
public static void main(String[] args) throws UnsupportedEncodingException {
String password = "F1C0T0N83LL34";
String message = "{\"version\":\"1.0\",\"rccCubeType\":\"TCR_CASE_D\",\"timeZone\":\"Asia/Kolkata\",\"timeOffset\":\"+05:30\",\"tenant\":\"0001\",\"extractionTime\":\"20170713162718117\"}";
AESEncrypter encrypter = new AESEncrypter(password);
String cipher = encrypter.encrypt(message);
System.out.println(cipher);
System.out.println(new String(encrypter.decrypt("I8YbMaRvAw+rzPQu//uXnDDFrk/EtscXpcxBzqonVOpJ1VjvpwtRGwrsEz9R1rroC95Vj9bzPDbkX2qdLXK4jLKlzaoINXOxF+dHslnBVl3xG61qh9QdCuMTBzEEw18K51JJu+13bjuUO20+0uZiY5q6Wg1sQ60C0QEeO/7K9F/TSUN1r5l02Q9NSDQJpkvlglHZEfPJ7ST4179oqlQUjQ==").getBytes("UTF-8")));
}
}
我正在使用dcipher对象解密加密的字符串,但是当我复制加密字符串的值并执行复制字符串的dcipher时,我会得到一些垃圾值,如
e_N���<�E=>�,"rccCubeType":"TCR_CASE_D","timeZone":"Asia/Kolkata","timeOffset":"+05:30","tenant":"0001","extractionTime":"20170713162718117"}
我哪里错了?当我在一次运行的内存中处理这些东西时,解密就会正确进行。
编辑1:添加完整的课程
答案 0 :(得分:1)
您需要提供加密字符串时使用的 IV 。在这里,您只需初始化加密密码并获取它生成的随机 IV - 这不会起作用,它必须是您实际进行加密时使用的密码。
您需要在加密时提出处理 IV 的方案,以便在需要解密时使用。一种常用的方法是使用 IV 为加密邮件添加前缀。因此,当您需要解密时,它随时可用。它不需要保密。