2013-10-19 124 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字节。