Rijndael Algorithm

mike55

Contributor
Joined
Mar 26, 2004
Messages
727
Location
Ireland
Hi

I am attempting to use the Rijndael algorithm for encrypting and decrypting sql server username and password. I have been successful in the generation of the key and the IV, and in the encryption and decryption of the data. My problem arises when I attempt to store the key and IV in an external location.

Both the key and the IV are bytes(), I have a simple method that can convert the byte() into a string:
Visual Basic:
private function convertToString( byVal data as byte()) as string
dim enc as System.text.asciiencoding = new system.text.asciiencoding
converttostring = enc.getstring(data)
return converttostring
end function

I also have a function that converts the string data into a byte():
Visual Basic:
private function convertToByte(byVal data as string) as byte()
return (new unicodeencoding).getbytes(<<String data>>)
end function

When I attempt to user the IV in the decoding method I get the following error:
System.security.cryptography.cryptographicexception: Specified initialization vertoc (IV) does not match the block size for this algorith.

My encryption is:
Visual Basic:
dim fStream as filestream = file.open(filename, filemode.openorcreate)
dim rijndaelalg as rijndael = rijndael.create
dim cStream as new cryptostream)fstream, rijndaelalg.createEncryptor(key, IV), CryptoStreamMode.Write)
Dim sWriter as new streamwriter(cstream)
swriter.writeline(plaintext)

My decryption is:
Visual Basic:
dim fstream as filestream = file.open(filename, filemode.openorcreate)
dim rijndaelalg as rijndael = rijndael.create
dim cstream as new cryptostream(fstream, rijndaelalg.createdecryptor(convertToByte(key), convertToByte(IV)), CryptoStreammode.read)
dim sreader as new streamreader(cstream)
dim val as string = sreader.readline

Appreciate any suggestions.

Mike55
 
Last edited by a moderator:
PlausiblyDamp said:
Have you tried using the same encoding for both operations? In the convert to string routine you use ascii while converting back you use unicode.

Hi PlausiblyDamp

I have changed the methods for converting to string and byte to the following:

Visual Basic:
public function convertToByte(byVal data as string) as byte()
return (new unicodeencoding).getbyte(data)
end function

Visual Basic:
public function convertToString(byval data as byte()) as string
return (new unicodeencoding).getstring(data)
end function

I am getting a padding exception with the IV.

Mike55.
 
Last edited by a moderator:
Too be honest converting to and from a string like that has many possible failings, any conversions assume a corresponding character mapping for any given byte sequence; and more importantly that it will always be converted back the same way.

If you are just after a string that can be stored in a config file or similar Base64 encoding is probably your best bet. You could replace your two methods will direct calls to Convert.ToBase64String and Convert.FromBase64String.
 
Hi PlausiblyDamp,

I took your suggestion and changed the relevent code to Convert.toBase64String and Convert.FromBase64String. I still seem to be getting the same error:
System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed." Everything else is working fine.

Mike55.
 
PlausiblyDamp said:
How are you saving / loading the Key and IV? Is there any chance you coul attach a simple app that exhibits this problem?

Based on your first question, I am using a web service to do the encrypting and decrypting. Base on the return by the web service, I simply copy and paste the return into a notepad file. When trying to test the decode I copy and paste from the notepad file. Therefore, is it possible that when I copy from the notepad file that I am unknownly picking up extra data??

Here is a copy of all my code, I am storing it in a single .vb file so I can experiment with the code. The function DecryptTextFromFile2 is what I am using to decrypt.

Code:
Imports System.web
imports system.web.services
imports system.web.services.protocols
imports system
imports system.text
imports system.security.cryptography

dim RijndaelAlg as Rijndael = Rijndael.create

Public Function StartEncryption(ByVal plaintext As String) As String
        StartEncryption = Nothing
        Try
            Dim RijndaelAlg As Rijndael = Rijndael.Create
            Dim fileName As String = "C:\Documents and Settings\All Users\Documents\CText.text"

            EncryptTextToFile(plaintext, fileName, RijndaelAlg.Key, RijndaelAlg.IV)

            Dim final As String = DecryptTextFromFile(fileName, RijndaelAlg.Key, RijndaelAlg.IV)
            Return final
        Catch ex As Exception

        End Try
    End Function

    <WebMethod()> _
    Public Function getKey() As String
        'Return convertToString(RijndaelAlg.Key)
        Return Convert.ToBase64String(RijndaelAlg.Key)
    End Function

    <WebMethod()> _
    Public Function getIV() As String
        'Return convertToString(RijndaelAlg.IV)
        Return Convert.ToBase64String(RijndaelAlg.IV)
    End Function

    Private Sub EncryptTextToFile(ByVal data As String, ByVal filename As String, ByVal key() As Byte, ByVal IV() As Byte)
        Dim fStream As FileStream = File.Open(filename, FileMode.OpenOrCreate)

        Dim RijndaelAlg As Rijndael = Rijndael.Create
        Dim cStream As New CryptoStream(fStream, RijndaelAlg.CreateEncryptor(key, IV), CryptoStreamMode.Write)

        Dim sWriter As New StreamWriter(cStream)

        Try
            sWriter.WriteLine(data)

        Catch ex As Exception
        Finally
            sWriter.Close()
            cStream.Close()
            fStream.Close()
        End Try
    End Sub

    Private Function DecryptTextFromFile(ByVal filename As String, ByVal key() As Byte, ByVal iv() As Byte) As String
        DecryptTextFromFile = Nothing
        Dim fstream As FileStream = File.Open(filename, FileMode.OpenOrCreate)

        Dim rijndaelalg As Rijndael = Rijndael.Create
        Dim cStream As New CryptoStream(fstream, rijndaelalg.CreateDecryptor(key, iv), CryptoStreamMode.Read)
        Dim sreader As New StreamReader(cStream)

        Dim val As String = Nothing
        Try
            val = sreader.ReadLine
            Return val
        Catch ex As Exception
        Finally
            sreader.Close()
            cStream.Close()
            fstream.Close()
        End Try
    End Function

    <WebMethod()> _
        Public Function DecryptTextFromFile2(ByVal filename As String, ByVal key As String, ByVal iv As String) As String
        DecryptTextFromFile2 = Nothing
        Dim fstream As FileStream = File.Open(filename, FileMode.OpenOrCreate)

        Dim rijndaelalg As Rijndael = Rijndael.Create
        Dim cStream As New CryptoStream(fstream, rijndaelalg.CreateDecryptor(Convert.FromBase64String(key), Convert.FromBase64String(iv)), CryptoStreamMode.Read)
        Dim sreader As New StreamReader(cStream)

        Dim val As String = Nothing
        Try
            val = sreader.ReadLine
            Return val
        Catch ex As Exception
        Finally
            sreader.Close()
            cStream.Close()
            fstream.Close()
        End Try
    End Function

    Public Function convertToByte(ByVal data As String) As Byte()
        Return (New UnicodeEncoding).GetBytes(data)
    End Function

    Public Function convertToString(ByVal data As Byte()) As String
        Return (New UnicodeEncoding).GetString(data)
    End Function

Mike55.
 
Last edited:
A quick sample hacked from your code - rather than loading and saving the key & IV anywhere they are just displayed / read from a couple of textboxes.

Text to encrypt is entered into the large textbox and will be written out to a file, decrypted text will be displayed in a label beneath it.
 

Attachments

Last edited:
Back
Top