2017-06-19 41 views
1

嘗試使用javax.crypto庫來加密字符串並將其存儲在數據庫(Oracle)中。以後我需要解密這個字符串,所以我需要一個雙向算法。java加密字符串不能存儲在數據庫中

問題是數據庫似乎不接受方法創建的一些加密字符。我們正在將我們的數據庫遷移到新的服務器之間。舊數據庫使用US7ASCII字符集,而新數據庫使用AL32UTF8。當我將加密的字符串放入數據庫時​​,數據庫會將它們轉換爲US7ASCII數據庫中的問號(?)。它似乎在AL32UTF8數據庫中存儲得很好。

所以,我必須使這個交叉兼容。我嘗試使用getBytes()方法發送不同的StandardCharsets值,但它似乎沒有幫助。也許我錯過了一些東西。任何方式,我可以得到所需的結果做不同?

這是我的代碼來生成密文。從另一篇文章StackOverflow

import java.io.PrintStream; 
import javax.crypto.Cipher; 
import javax.crypto.spec.SecretKeySpec; 
import java.nio.charset.StandardCharsets; 

public class test 
{ 

    public static void main(String[] args) 
    throws Exception 
    { 
     //byte[] encryptionKey = "Es6XYPkgCV75J95Y".getBytes(StandardCharsets.UTF_8); 
     byte[] encryptionKey = "Es6XYPkgCV75J95Y".getBytes(StandardCharsets.ISO_8859_1); 
     //byte[] plainText = args[0].getBytes(StandardCharsets.UTF_8); 
     byte[] plainText = args[0].getBytes(StandardCharsets.ISO_8859_1); 
     MyCrypto aes = new MyCrypto(encryptionKey); 
     byte[] cipherText = aes.encrypt(plainText); 
     byte[] decryptedCipherText = aes.decrypt(cipherText); 

     System.out.println(new String(plainText)); 
     System.out.println(new String(cipherText)); 
     System.out.println(new String(decryptedCipherText)); 
    } 

} 

class MyCrypto 
{ 
    private byte[] key; 

    private static final String ALGORITHM = "AES"; 

    public MyCrypto(byte[] key) 
    { 
     this.key = key; 
    } 

    /** 
    * Encrypts the given plain text 
    * 
    * @param plainText The plain text to encrypt 
    */ 
    public byte[] encrypt(byte[] plainText) throws Exception 
    { 
     SecretKeySpec secretKey = new SecretKeySpec(key, ALGORITHM); 
     Cipher cipher = Cipher.getInstance(ALGORITHM); 
     cipher.init(Cipher.ENCRYPT_MODE, secretKey); 

     return cipher.doFinal(plainText); 
    } 

    /** 
    * Decrypts the given byte array 
    * 
    * @param cipherText The data to decrypt 
    */ 
    public byte[] decrypt(byte[] cipherText) throws Exception 
    { 
     SecretKeySpec secretKey = new SecretKeySpec(key, ALGORITHM); 
     Cipher cipher = Cipher.getInstance(ALGORITHM); 
     cipher.init(Cipher.DECRYPT_MODE, secretKey); 

     return cipher.doFinal(cipherText); 
    } 
} 
+1

您是否試過Base64?帶有字符編碼的字符串通常不是二進制數據的有效容器。 –

+1

如何將加密字符串放入數據庫並將其取回或檢查,以及將其存儲爲哪種數據類型?顯示問題的字符串/值的示例也可能有用。你也可以使用'dump()'函數來查看真正存儲的內容。也許這只是您客戶中的顯示問題。 –

+0

數據庫字段是Varchar2字段。由於數據庫是第三方,因此無法修改數據類型。我基本上使用我上面發佈的程序來複制和粘貼到數據庫中的值。我將以編程方式從數據庫中檢索它。 – mang

回答

5

當你加密數據你把它變成二進制數據。這聽起來像是你試圖將它作爲字符數據存儲,這是一個壞主意。

你真的有兩個選擇;

  1. 使用諸如Base64的二進制到文本方案對加密的二進制數據進行編碼。然後您可以將編碼數據存儲爲字符數據。當你想檢索它時,你需要在解密之前閱讀字符數據並解碼(text to binary)。

  2. 將加密的二進制數據存儲爲二進制數據(例如BLOB)。

+0

我會給選項1一個嘗試。無法更改字段的數據類型 – mang

相關問題