2013-07-19 68 views
0

我想存儲數據(用DES加密),然後從數據庫中取出加密數據並將其作爲列表顯示。但我有一個問題。這是代碼。解密來自數據庫的數據時出現的「javax.crypto.IllegalBlockSizeException」

public void EncryptDemo(){ 
    try { 
     FileInputStream keyfis = new FileInputStream("mainkey.key"); 
     byte[] encodedKey = new byte[keyfis.available()]; 
     keyfis.read(encodedKey); 
     keyfis.close(); 
     Key KeyFromFile = new SecretKeySpec(encodedKey, "DES"); 
     Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
     String text=txtToEncryptData.getText(), output; 
     cipher.init(Cipher.ENCRYPT_MODE, KeyFromFile); 
     DataDemo = cipher.doFinal(text.getBytes()); 
     InsertIntoDataBase(); 
     //I store it as varbinary in database 
    } catch (FileNotFoundException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (IOException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (NoSuchAlgorithmException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (NoSuchPaddingException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (InvalidKeyException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (IllegalBlockSizeException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (BadPaddingException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

    public void DecryptDemo(){ 
    try { 
     FileInputStream keyfis = new FileInputStream("mainkey.key"); 
     byte[] encodedKey = new byte[keyfis.available()]; 
     keyfis.read(encodedKey); 
     keyfis.close(); 
     Key KeyFromFile = new SecretKeySpec(encodedKey, "DES"); 
     Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, KeyFromFile); 
     String sql = "{call SelectAll}"; 
     CallableStatement call = conn.prepareCall(sql); 
     call.execute(); 
     ResultSet result = call.getResultSet(); 
     DefaultListModel model = new DefaultListModel(); 
     while(result.next()){ 
      DataDemo = result.getBytes("TestData"); 
      byte[] plainText = cipher.doFinal(DataDemo); 
      String after = new String(plainText); 
      model.addElement(after); 
     } 
     lstDecryptResult.setModel(model); 
    } catch (SQLException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (FileNotFoundException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (IOException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (NoSuchAlgorithmException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (NoSuchPaddingException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (InvalidKeyException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (IllegalBlockSizeException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (BadPaddingException ex) { 
     Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

加密和存儲是可以的。但是,當我從數據庫中的數據,我得到這個錯誤時解密(在字節[]明文= cipher.doFinal(DataDemo);)

Jul 19, 2013 11:40:05 AM databaseencryptdecryptdemo.MainGUI DecryptDemo 
SEVERE: null 
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher 

任何人有一個解決方案???

+0

什麼是您的數據庫?如果SQLite,將加密數據存儲爲「blob」。無論數據庫是什麼,你都需要選擇一個數據類型來存儲和返回「純二進制」與字符或數字數據。 –

+0

我使用Microsoft SQL Server 2012 :) –

回答

0

我找到了解決方案。但我認爲這不是最好的。

我將表DataDemo的類型從varbinary更改爲圖像,一切都變成了正常。但是我在數據庫中的數據大小存儲比(大約4倍)大於oigin數據。

但至少我解決了我的問題。

有沒有人有更好的解決方案?我願意收到你的來信。

0

您應該將DataDemo變量分成8個字節段。

public List<Byte[]> divideInto8(Byte[] bytes) { 
    int length = bytes.length; 
    List<Byte[]> returnValues = new ArrayList<Byte[]>(); 
    for (int i = 0; i < length; i = i + 8) { 
     Byte[] thebytes = new Byte[8]; 
     for (int j = 0; j < 8; j++) { 

      thebytes[j] = bytes[i * 8 + j]; 
     } 
     returnValues.add(thebytes); 
    } 
    return returnValues; 
} 
+0

我該怎麼做? –

+0

可能有更好的解決方案,但這也是一個解決方案。我編輯了答案。注意:我沒有測試代碼,但它應該是這樣的。 –