2017-07-13 58 views
0

我有一個JSON字符串使用導致錯誤的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對象解密所述加密的字符串這個字符串的java cryto包解密JSON字符串,但是當我複製加密的字符串的值,並做複製的字符串的一個dcipher我得到一些垃圾值,如

e_N���<�E=>�,"rccCubeType":"TCR_CASE_D","timeZone":"Asia/Kolkata","timeOffset":"+05:30","tenant":"0001","extractionTime":"20170713162718117"} 

我哪裏錯了?當我在單次運行的內存中處理這些內容時,解密過程是正確的。

編輯1:將完整的類

+0

我認爲問題與祕密有關。一次加密和解密時使用同一個祕密。當您複製加密的代碼並嘗試解碼時,您需要使用先前已加密的相同密碼 –

+0

它適用於我。您沒有顯示實際給您提供問題的代碼。 –

+0

您是否使用相同的AESEncrypter實例進行加密解密? – bowmore

回答

1

您需要提供加密字符串時使用的IV。在這裏,您只需初始化一個加密密碼,然後隨機生成它 - 這不起作用,它需要是實際進行加密時使用的密碼。

你需要想出一個方案來處理加密時的IV,所以當你需要解密的時候就有了它。通常使用的方法是在加密消息前加上IV。所以當你需要解密的時候它就很容易得到。它不需要保密。

+0

不,他確實提取了用於加密的IV,並將其設置在解密密碼中。 –

+0

他不用它加密..他只是初始化一個密碼,並採取四。 –

+0

一個加密的字符串搞砸頭是一個經典的混亂IV。 –