2012-09-25 136 views
-1

我有一個預先編寫的代碼,用於對給定的純文本進行加密,反之亦然。無法更改Base64解碼器中的密碼密鑰

該類有3種方法,其中可以分別使用2種方法進行加密和解密。

public class SqlCipherUtil { 

    private Cipher ecipher; 
    private Cipher dcipher; 

    public String encryptString(String pStrPlainText) { 

     try { 
      generateKey(); 
      byte[] utf8 = pStrPlainText.getBytes("UTF8"); 
      byte[] enc = this.ecipher.doFinal(utf8); 
      return new BASE64Encoder().encode(enc); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    public String decryptString(String pStrCipherText){ 

     try { 
      generateKey(); 
      byte[] dec = new BASE64Decoder().decodeBuffer(pStrCipherText); 
      byte[] utf8 = this.dcipher.doFinal(dec); 
      return new String(utf8, "UTF8"); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    /** 
    * This method is used to generate the encrypted key. 
    */ 
    private void generateKey() { 

     try { 
      byte[] decodedStr = new BASE64Decoder().decodeBuffer("rA/LUdBA/hA="); 
      SecretKey key = new SecretKeySpec(decodedStr, "DES"); 
      this.ecipher = Cipher.getInstance("DES"); 
      this.dcipher = Cipher.getInstance("DES"); 
      this.ecipher.init(1, key); 
      this.dcipher.init(2, key); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

鍵存在於類的不能在線路byte[] decodedStr = new BASE64Decoder().decodeBuffer("rA/LUdBA/hA=");, 改爲任何其他鍵 和它給一個異常。

java.security.InvalidKeyException: Invalid key length: 9 bytes 
    at com.sun.crypto.provider.DESCipher.engineGetKeySize(DashoA13*..) 
    at javax.crypto.Cipher.b(DashoA13*..) 
    at javax.crypto.Cipher.a(DashoA13*..) 
    at javax.crypto.Cipher.a(DashoA13*..) 
    at javax.crypto.Cipher.a(DashoA13*..) 
    at javax.crypto.Cipher.init(DashoA13*..) 
    at javax.crypto.Cipher.init(DashoA13*..) 

我嘗試了下面的代碼,我正好在數組中獲得8個字節。

public static void main(String[] args) throws IOException { 
     byte[] decodedStr = new BASE64Decoder().decodeBuffer("rA/LUdBA/hA="); 

     for(byte b : decodedStr){ 
      System.out.print(b); 
      System.out.print(" "); 
     } 
    } 

} 

關鍵的任何其他組合將使字節數組的大小超過8比7

什麼是背後得到字節數組的大小8的概念少了?

應該如何使用自定義組合鍵或我們的自定義生成的鍵?

請回答這兩個問題。

+0

在初始化代碼對我的作品......你確定嗎?你已經準備好了那些代碼? –

+0

如果密鑰只是「rA/LUdBA/hA =」,代碼對我來說工作正常。 如果我們改變密鑰,我會得到一個異常。 嘗試一下自己,將密鑰更改爲不同的密鑰, 在主程序中嘗試調用 新的SqlCipherUtil()。encryptString(「jon-skeet」); 你會得到一個例外。 – bali208

回答

0

如果您的目標是對字符串進行編碼和解碼,請使用Base64

public class PasswordCodecHandler { 
     Base64 codec = null; 

     public PasswordCodecHandler() { 
      codec = new Base64(); 
     } 

     public String encode(String password) { 
      byte[] temp; 
      String encodedPassword = null; 
      temp = codec.encode(password.getBytes()); 
      encodedPassword = new String(temp); 
      return encodedPassword; 
     } 

     public String decode(byte[] encodedPassword) { 
      byte[] temp; 
      String decodedPassword; 
      temp = codec.decode(encodedPassword); 
      decodedPassword = new String(temp); 
      return decodedPassword; 
     } 

     public static void main(String[] args) { 
      PasswordCodecHandler passwordCodecHandler = new PasswordCodecHandler(); 
      String s1 = passwordCodecHandler.encode("password"); 
      System.out.println(s1); 

      String s2 = passwordCodecHandler.encode("admin"); 
      System.out.println(s2); 

      String s3 = passwordCodecHandler.encode("administrator"); 
      System.out.println(s3); 

      String s4 = passwordCodecHandler.encode("123456"); 
      System.out.println(s4); 

     } 
    } 

對於其他數據類型:它可以根據你的內存分配大小

/* Download apache common-io.xxx. jar*/ 

    public class CodecHandler { 
     Base64 codec = null; 

     public CodecHandler() { 
      codec = new Base64(); 
     } 

     public byte[] encode(byte[] decoded) { 
      return codec.encode(decoded); 
     } 

     public byte[] decode(byte[] encoded) { 
      return codec.decode(encoded); 
     } 

     public static void main(String[] args) throws IOException { 
      File file = new File("D:/Test.mp4"); 
      byte[] fileByteArray = FileUtils.readFileToByteArray(file); 
      CodecHandler codecHandler = new CodecHandler(); 
      byte[] encoded = codecHandler.encode(fileByteArray); 
      System.out.println("Byte Size : " + encoded.length); 
      byte[] decode = codecHandler.decode(encoded); 
      FileUtils.writeByteArrayToFile(new File("C:/Test.mp4"), decode); 


     } 
    } 
2

密鑰的任何其它組合將使字節數組的大小更 大於8或小於7

我懷疑。您可能會添加或刪除錯誤的字符;或者在錯誤的位置。請參閱:http://en.wikipedia.org/wiki/Base64

是的9字節不是DES的有效密鑰長度。你可以簡單地縮短到適當的長度。你得到9個字節,因爲你的base64字符串是3×4個字符長,將被解碼爲3×3 = 9個字符。修剪輸出。

獲取字節數組大小8的概念是什麼?

DES使用56位密鑰。 8字節= 64位,密鑰的位數足夠。

應該做些什麼來使用自定義組合鍵或我們的自定義生成的鍵?

讓用戶輸入一個至少有7個字符(56位)的密鑰。 我真的不明白你爲什麼在這個示例中使用base64 - 可能只是因爲你從某處複製它?你只需要幾個隨機字節。獲取這些內容的常用方法是從用戶給出的任何輸入中構建一個散列,並使用該散列中的字節。

+0

如果密鑰只是「rA/LUdBA/hA =」,代碼對我來說工作正常。如果我改變密鑰,我會得到一個異常。自己嘗試一下,將密鑰更改爲不同的密鑰,在主程序中嘗試調用新的SqlCipherUtil()。encryptString(「JoSO」); – bali208

+0

DES使用8字節密鑰,但忽略每個字節的LSB,原來LSB用於奇偶校驗。 – zaph

0

什麼是背後得到字節數組的大小8概念是java.lang.OutOfMemoryError

你的新的基於-64 –編碼的密鑰必須是12個字符長,一個,只有一個,=字符結尾。

在base-64中,字符=是一個填充字符,它只能出現在編碼字符串的末尾。 Base-64編碼從每個3字節的輸入塊輸出一個4個字符的塊。如果輸入長度不是3的倍數,則填充最後一個塊。

在編碼密鑰「rA/LUdBA/hA =」中,有12個字符,它們可以編碼9個字節。但最後一個字符是填充,這意味着最後一個字節應該被忽略,留下8個字節。

應該做些什麼來使用自定義組合鍵或我們的自定義生成的鍵?

首先,你不應該使用DES。這太弱,不安全。但總的來說,在Java中生成安全密鑰的正確過程是使用KeyGenerator類。對於(不安全)DES,即可生成密鑰,並與基地-64編碼是這樣的:

import java.util.Base64; 
import javax.crypto.KeyGenerator; 
import javax.crypto.SecretKey; 

… 

KeyGenerator gen = KeyGenerator.getInstance("DES"); 
gen.init(56); 
SecretKey secret = gen.generateKey(); 
String b64 = Base64.getEncoder().encodeToString(secret.getEncoded()); 
System.out.println(b64); 

使用密鑰,這樣對其進行解碼:

import java.util.Base64; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeySpec; 

… 

SecretKey key = new SecretKeySpec(Base64.getDecoder().decode(b64), "DES");