下面这段程序,相信很多读过ASP.NET技术内幕这本书的朋友都很熟悉,是讲对称加密的,为了测试方便,我用WINDOW FORM测试了这段程序,程序如下:    
    Const DESKEY As String = "ABCDEFGH"
    Const DESIV As String = "HGFEDCBA"
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim arrDesKey As Byte()
        Dim arrDesIV As Byte()
        Dim arrinput As Byte()
        Dim objFileStream As FileStream
        Dim objEDS As DESCryptoServiceProvider
        Dim objEncryptor As ICryptoTransform
        Dim objCryptoStream As CryptoStream
        arrDesKey = Convert2Byte(DESKEY)
        arrDesIV = Convert2Byte(DESIV)
        arrinput = Convert2Byte(TextBox1.Text) '注意这个地方①
        objEDS = New DESCryptoServiceProvider
        objEncryptor = objEDS.CreateEncryptor(arrDesKey, arrDesIV)
        objFileStream = New FileStream("d:\test.txt", FileMode.Create, FileAccess.Write)
        objCryptoStream = New CryptoStream(objFileStream, objEncryptor, CryptoStreamMode.Write)
        objCryptoStream.Write(arrinput, 0, arrinput.Length)
        'Console.WriteLine(objCryptoStream.Position)
        Console.WriteLine(objFileStream.Length) '注意这个地方②
        objCryptoStream.Close()
    End Sub
    Private Function Convert2Byte(ByVal strInput As String) As Byte()
        Dim arrChar() As Char
        arrChar = strInput.ToCharArray
        Dim arrByte(arrChar.Length - 1) As Byte
        For i As Integer = 0 To arrByte.Length - 1
            arrByte(i) = Convert.ToByte(arrChar(i))
        Next
        Return arrByte
    End Function
无论文本框中输入多长的字符串,程序执行都完全正常,在D盘下面也生成了test.txt这个文件,打开这个文件,里边也有加过密的内容(一些乱码),同时经过测试,test.txt中的内容也能够被很好的解密,一切看起来都很正常。
现在请注意②处,我的疑问在这里,当①处文本框中输入的内容(需要加密的内容)小于8个字母,那么②处输出的流的长度竟然是0,打开生成的test.txt文件,里边同样有被加密过后的内容;当文本框中输入的字母长度大于8小于16时,输出流的长度一直为8,当输入字母长度大于16小于32时,输出流长度一直为16,以此类推现在我非常不解,为何会出现这种现象,特别是当输入字母长度小于8时,为何FileStream流的长度为0?既然流的长度为0,为何test.txt中还会出现加密后的内容?

解决方案 »

  1.   

    To:lovelxj(爱生活爱芳芳)
    谢谢参与,呵呵~~希望有人能够给出一个系统的说明
      

  2.   

    I am not a Cryptographer, but1. the reason you see 0 for the first case is because there are some bits left in the stream, call Flush() will not work, you have to callobjCryptoStream.FlushFinalBlock()
    Console.WriteLine(objFileStream.Length) 2. the reason you see 8,16,24,.... because DES algorithm is padded by the block, the block length is 64 bits --> 8 bytes, seehttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemsecuritycryptographysymmetricalgorithmclasspaddingtopic.asp
      

  3.   

    实验了一下,觉得FileStream.Length似乎并不是直接的Writer,只是让CryptoStream利用它的某些函数,然后Microsoft的某个家伙认为应该给FileStream留点什么,于是就来了个OldLength%8。
      

  4.   

    上面我的回复请忽略。
    试了一下Saucer的,是因为没有Flush完。
      

  5.   

    感谢大家的参与~~每次看到思归的答案总能让我心旷神怡,现在了解个大概,我还要去仔细想想思归说的这个SymmetricAlgorithm.Padding
    还是不太理解为何要"padded by the block"?这样做有什么意义呀?
    如果思归还在,劳驾~~
      

  6.   

    TO:CCsdnCC(学研)
    哈哈,为什么要忽略你的回复?看到大家都来参与,非常高兴,感谢大家~只有讨论,才能出真理嘛
      

  7.   

    I said I am not a Cryptographer, but DES is a block cipher algorithm, read about the padding herehttp://www.di-mgt.com.au/cryptopad.html
      

  8.   

    CryptoStream.FlushFinalBlock() 其实是说,你的任务做完了,该Pad就Pad吧
      

  9.   

    好~研究一下,然后该Pad就Pad,呵呵