Cryptostream to bytes or memorystream

jwhite128

New member
Joined
May 28, 2007
Messages
3
Programming Experience
3-5
I am trying to decrypt an encrypted file on the fly when the user clicks to download a file from a website. The code I have only keeps returning only 1 byte from a test file that is 18K. What I am trying to do is to access the physical file on the server, decrypt it into the memorystream or streamreader so that it doesn't have to physically write it to the drive, and the decrypted file will be flushed after it has been downloaded.
VB.NET:
Function DecryptFile(ByVal sInputFilename As String, ByVal sKey As String) As Byte()

Dim DES As New DESCryptoServiceProvider() 
DES.Key() = ASCIIEncoding.ASCII.GetBytes(sKey)

DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey)

Dim fsread As New FileStream(sInputFilename, FileMode.Open, FileAccess.Read) 
Dim desdecrypt As ICryptoTransform = DES.CreateDecryptor()

Dim cryptostreamDecr As New CryptoStream(fsread, desdecrypt, CryptoStreamMode.Read) 
Dim decryptedStream As MemoryStream = New MemoryStream()

Dim fsDecrypted As New StreamWriter(decryptedStream)
Dim btFile As Byte() = New Byte(decryptedStream.Length) {} 
decryptedStream.Read(btFile, 0, Convert.ToInt32(decryptedStream.Length))

Return btFile

End Function

 

Private Sub cmdDownload_Click(ByVal Sender As System.Object, ByVal e As EventArgs) Handles lnkTest.Click 
Dim strFilename As String = "c:\testing\test._pdf"

Dim objFile As System.IO.FileInfo = New System.IO.FileInfo(strFilename) 
If objFile.Exists Then

System.Web.HttpContext.Current.Response.ClearContent()

System.Web.HttpContext.Current.Response.Buffer = True

System.Web.HttpContext.Current.Response.Clear()

System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" & "test.pdf") 
System.Web.HttpContext.Current.Response.AddHeader("Content-Length", CStr(objFile.Length))

System.Web.HttpContext.Current.Response.AddHeader("Content-Type", "application/pdf") 
System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream"

System.Web.HttpContext.Current.Response.BinaryWrite(DecryptFile(strFilename, "12345678")) 
System.Web.HttpContext.Current.Response.End()

System.Web.HttpContext.Current.Response.Flush()

End If

End Sub
 
Last edited by a moderator:
A couple of issues:
The decryption algoritm: Your current code doesn't use any of the decryption stuff you have set up. Turn your cryptostreamDecr (the CryptoStream) to write mode and wrap it around decryptedStream (the MemoryStream), then write all your encrypted source bytes to cryptostreamDecr. When you are done the decrypted bytes will be in decryptedStream, where you can call its ToArray() method to get the byte array.

The response: You now set the response content length equal to the encrypted bytes length, there is no guarantee the decrypted byte array will be the same length, I would say it never is equal but usually is larger so one would "get away with it" even if current header value is erroneous. Flush doesn't work after response is End'ed, so in the cases it is needed you'd have to swap these statements for it to take effect. AddHeader method is depreciated, use AppendHeader.
 
VB.NET:
Function DecryptFile(ByVal sInputFilename As String, ByVal sKey As String) As Byte()
    Dim DES As New DESCryptoServiceProvider()
    DES.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(sKey)
    DES.IV = System.Text.ASCIIEncoding.ASCII.GetBytes(sKey)
    Dim decMem As New IO.MemoryStream
    Dim cryptostreamDecr As New CryptoStream(decMem, DES.CreateDecryptor(), CryptoStreamMode.Write)
    Dim inputbytes() As Byte = My.Computer.FileSystem.ReadAllBytes(sInputFilename)
    cryptostreamDecr.Write(inputbytes, 0, inputbytes.Length)
    cryptostreamDecr.FlushFinalBlock()
    cryptostreamDecr.Close()
    Return decMem.ToArray
End Function
 
Back
Top