StrataFrame Forum

Can't decrypt encrypted file (Error: Lenght of the encrypted data is invalid)

http://forum.strataframe.net/Topic27166.aspx

By dgsoft - 5/18/2010

Hi,

I try to encrypt and store files in SQL Server database [binarydata] VarChar(MAX) field..

Problem is.. I can't DECRYPT already ecnrypted file.. (with strings I have no problem)



1) Way to encrypt and SaveFile in the Database



Dim loEncrypt As MicroFour.StrataFrame.Security.Encryption.TripleDESWrapper = New MicroFour.StrataFrame.Security.Encryption.TripleDESWrapper

loEncrypt.EncryptFile(lcFilename)

Dim lcSQLExpr = String.Format("UPDATE [ErpData].[dbo].[KONTAKTE_DOKUMENTE] SET [BinaryData] = (SELECT BulkColumn FROM OPENROWSET(BULK '{0}', SINGLE_BLOB) AS InsertData) WHERE PK_ID = {1}", lcFilename, tnDocumentId)

If Me.ExecuteNonQuery(lcSQLExpr) > 0 Then

File.Delete(lcFilename)

End If



==== On this step I encrypt the file and save data into binarydata field



2) I try to restore and decrypt file



' Here is "ME" is businessObject.



Dim fs As FileStream = New FileStream(lcFilename, FileMode.CreateNew, FileAccess.Write)

Dim bw As BinaryWriter = New BinaryWriter(fs)

bw.Write(Me.binarydata, 0, Me.binarydata.Length)

bw.Flush()

bw.Close()

fs.Close()

Dim loEncrypt As MicroFour.StrataFrame.Security.Encryption.TripleDESWrapper = New MicroFour.StrataFrame.Security.Encryption.TripleDESWrapper



Try

loEncrypt.DecryptFile(lcFilename)

lcReturn = lcFilename

Catch ex As Exception

MicroFour.StrataFrame.Messaging.MessageForm.ShowMessage(ex.Message)

End Try



=======! HERE I'V GOT AN EXCEPTION "The length of the encrypted is invalid"



I expect something wrong with BinaryWriter.. but what?



Thanks

Denis


By Greg McGuffey - 5/18/2010

I don't have time to test your code, but in the mean time there are two things you might test:



First, does the encryption/decryption work if you just encrypt the file, then decrypt it? This would isolate the problem to either the encryption related code or the database related code.



Second, you might consider providing a key and vector to the TripleDESWrapper constructor.



When I get a chance (if you haven't already figured it out), I'll run a quick test to see what I come up with.
By dgsoft - 5/18/2010

Hi Greg,

Thanks for response.

1) Yes. When I do decrypt, and encrypt file on disk - it works perfect.

I thinking the problem with BinaryWriter because my original before attach to database is 184Kb,

And after BinaryWriter.Write file - its 280Kb..



I change my code..

Dim fs As FileStream = New FileStream(lcFilename, FileMode.CreateNew, FileAccess.Write)

Dim bw As BinaryWriter = New BinaryWriter(fs)

Dim encoding As System.Text.ASCIIEncoding = New System.Text.ASCIIEncoding

Dim loBytes As Byte() = encoding.GetBytes(Me.binarydata)

bw.Write(loBytes, 0, loBytes.Length)

bw.Flush()

bw.Close()

fs.Close()



But still have a problem - but now error message is diffrent. It says : Data is invalid..

Probably something wrong with Encoding



Thanks

Denis
By Greg McGuffey - 5/18/2010

I think the problem might be the EncryptFile method. It is marked as obsolete and apparently causes major file corruption issues. Use the Encrypt/Decrypt methods instead. You can either open a stream and pass the bytes to these methods or read the contents and pass strings:



Dim loEncrypt As New TrippleDESWrapper()

Dim contents As String = File.ReadAllText(lcFilename)

Dim encryptedContents As String = loEncrypt.Encrypt(contents)

...

'-- Decrypt code

Dim encryptedContents = myBoInstance.ContentProperty

Dim contents As String = loEncrypt.Decrypt(encryptedContents )
By dgsoft - 5/19/2010

Hi,

Your code works only with Text files.. when I restore binary file like PDF to the disk.. the file is corrupt

RTF file reads ok.. PDF - not



Here I extracting file from database



Private Function mmks_DeryptFile(ByVal tcFilename As String, ByVal tlDecrypt As Boolean)

Dim lcReturnResult As String = tcFilename

Dim contents As String = Me.binarydata

'-- Decrypt code

If tlDecrypt Then

Dim loEncrypt As MicroFour.StrataFrame.Security.Encryption.TripleDESWrapper = New MicroFour.StrataFrame.Security.Encryption.TripleDESWrapper

Dim encryptedContents = Me.binarydata

contents = loEncrypt.Decrypt(encryptedContents)

End If



Dim fs As FileStream = New FileStream(tcFilename, FileMode.CreateNew, FileAccess.Write)

Dim bw As BinaryWriter = New BinaryWriter(fs)

Dim encoding As System.Text.ASCIIEncoding = New System.Text.ASCIIEncoding

Dim loBytes As Byte() = encoding.GetBytes(contents)

bw.Write(loBytes, 0, loBytes.Length)

bw.Flush()

bw.Close()

fs.Close()
By dgsoft - 5/19/2010

Ok.. Now for me it does not work with encoding/ without encoding .. the code next

In case when file NOT ENCRYPTED - the binary file stored on the disk correct.
When file is encrypted - I have a next :

Encrypting:
1) Dim contents As Byte() = File.ReadAllBytes(lcFilename)  LENGHT is 85668
2)  Dim encryptedContents As Byte() = loEncrypt.Encrypt(contents) - LENGHT is 85672

Decrypting:
1) Dim encryptedContents As Byte() = System.Text.Encoding.Unicode.GetBytes(contents)  - LENGHT is 85672
2) loBytes = loEncrypt.Decrypt(encryptedContents) - LENGHT is 85671 !!!!!!!!!!!!!!!!

and as result - file not readable..

Below my code

1) Attach file to the database

       If KontaktE_DOKUMENTEBO1.isembedded Then
            Dim lcFilename As String = KontaktE_DOKUMENTEBO1.location
            If File.Exists(lcFilename) Then
                If KontaktE_DOKUMENTEBO1.geschuetzt = True Then    ' When the document is password protected
                    Dim loEncrypt As MicroFour.StrataFrame.Security.Encryption.TripleDESWrapper = New MicroFour.StrataFrame.Security.Encryption.TripleDESWrapper
                    Dim contents As Byte() = File.ReadAllBytes(lcFilename)
                    Dim encryptedContents As Byte() = loEncrypt.Encrypt(contents)
                    Me.KontaktE_DOKUMENTEBO1.binarydata = System.Text.Encoding.Unicode.GetString(encryptedContents)
                Else
                    Dim loBytes As Byte() = File.ReadAllBytes(lcFilename)
                    Me.KontaktE_DOKUMENTEBO1.binarydata = System.Text.Encoding.Unicode.GetString(loBytes)
                End If
                Try
                    File.Delete(lcFilename)
                Catch ex As Exception
                    Dim lcMessage = ex.Message
                End Try
            End If
        End If


2) Restore File to the Disk Code

         Dim contents As String = Me.binarydata    'BusinessObject VarChar(MAX) field
        Dim loBytes As Byte()

'  When file neccessary to decrypt - then
        If tlDecrypt Then
            Dim loEncrypt As MicroFour.StrataFrame.Security.Encryption.TripleDESWrapper = New MicroFour.StrataFrame.Security.Encryption.TripleDESWrapper
            Dim encryptedContents As Byte() = System.Text.Encoding.Unicode.GetBytes(contents)
            loBytes = loEncrypt.Decrypt(encryptedContents)
        Else
'  When file not encrypted
            loBytes = System.Text.Encoding.Unicode.GetBytes(contents)
        End If
        Dim fs As FileStream = New FileStream(tcFilename, FileMode.CreateNew, FileAccess.Write)
        Dim bw As BinaryWriter = New BinaryWriter(fs)
        bw.Write(loBytes, 0, loBytes.Length)
        bw.Flush()
        bw.Close()
        fs.Close()

By dgsoft - 5/19/2010

Ok.

Now problem is fixed.

I choose wrong datatype for SQL Server field.



Now I change it to varbinary(MAX) and all works perfect



Thanks

Denis
By Ivan George Borges - 5/19/2010

Hi Denis.

I have created a sample following Greg's code and it works fine over here. To test it, I created a varbinary(MAX) in the Customer table of the StrataFrameSample database and used it to store a .pdf file (you will find it in the project folder itself) called TestPDF.pdf. You can find the sample at the SF Users Contributed Samples (http://forum.strataframe.net/Forum26-1.aspx)

There are two buttons, one encrypt the file and save the BO. The other reads the contents of the BO and creates a file on the Desktop (change the line where the FileStream is created to address your Desktop).

Hope it helps.

By Greg McGuffey - 5/19/2010

Glad you got it working!
By dgsoft - 5/19/2010

Hi Ivan,

Yes.. my main mistake was using wrong type.. varchar(max) instead varbinary(max), now it works without any conversion operation to string



Thanks for attention

Denis