2013-10-19 123 views
1

我正在使用Java來製作一個玩具程序,它使用DES加密來加密消息。我要加密的消息是:DES加密明文與密碼長度

String msg="This is a secret message"; 

對此我轉換爲字節爲:

byte [] msgBytes=msg.getBytes(); 

,並將其發送加密功能的工作原理如下:

//encryption function 
public static String encryptMsg(byte [] msgBytes, SecretKey myDesKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException 
{ 
    Cipher desCipher; 
    // Create the cipher 
    desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
    desCipher.init(Cipher.ENCRYPT_MODE, myDesKey); 
    byte[] textEncrypted = desCipher.doFinal(msgBytes); 

// converts to base64 for easier display. 
byte[] base64Cipher = Base64.encode(textEncrypted); 
return new String(base64Cipher); 
} //end encryptMsg 

然後,我顯示密碼,密碼和明文長度,我得到:

Encrypted Message: FDCU+kgWz25urbQB5HbFtqm0HqWHGlGBHlwwEatFTiI= 
Original msg length: 24 
Encrypted msg length: 44 

請問您能澄清一下,爲什麼密碼長度是44而原始消息長度是24?

編輯: 好的,我需要澄清的答案。密碼總是以=結尾。這可能是因爲填充?你能向我解釋爲什麼/這個密碼的長度是多少?總是以=結尾? 我的代碼是否正確或出現錯誤?我對編碼部分有疑問。

回答

2

有幾件事情怎麼回事:

  1. msg.getBytes()返回表示使用「平臺的默認字符集」的字符串編碼的字節(例如,可能是UTF-8 UTF-16 ..):specify the encoding manually避免混淆!在任何情況下,請參見msgBytes.length以獲得true純文本長度。

  2. DES,作爲一個塊暗號,將有輸出沿block size邊界填充 - 這將總是比純文本更大使用PKCS#5時,因爲純文本總是(參照msgBytes.length)長度用[1,8]字節填充。要查看加密大小是true,請參閱textEncrypted.length

  3. 加密字節使用base-64進行編碼,並且此過程與加密無關,因此會增加所需的字節數by about 33%(因爲每個字符/字節僅使用6位)。 Java base-64的實現也是adds padding,這是引入尾部「=」字符的地方。

只要您(或其他人用正確的算法和密鑰)可以檢索初始字符串 - 通過執行相反的順序每一步的倒數,那麼它的工作原理。如果一個特定的步驟沒有反向/反向操作或不能被「解除」,那麼有些事情是錯誤的;但這也意味着每一步都可以單獨測試


給號碼!

  1. msg.getBytes()返回一個ASCII/UTF-8編碼序列(如果使用UTF-16或另一種的另一 「寬」 編碼則以下號碼將太大)
  2. 因此,msgBytes.length是24
  3. 並且由於msgBytes.length模8爲0時,明文是填充與具有0x08的值的8個字節(每CKCS#5)
  4. 因此,textEncrypted.length是32(24個數據+ 8填充)
  5. 由於基-6- 4編碼,32字節* 1.33〜43個字符
  6. 並且使用base-64填充(=),最終結果爲44個字符!
2

DES加密的結果將總是8個字節的倍數。根據指定的填充算法,輸入也填充到8個字節的倍數。

base 64編碼將每3個字節編碼爲4個字符(3x8 = 4x6 = 24),並通過填充=字符確保輸出長度爲4的倍數。

所以,44個字符的輸出對應於33個字節,但=最後表示實際上只有32個字節。這很好,因爲使用PKCS5填充的24字節清除數據變爲32字節。