Home All Groups Group Topic Archive Search About

The Irish fada (áéíóú/ÁÉÍÓÚ) and encryption/decryption problem!

Author
17 Jan 2006 4:01 PM
almurph
Hi everyone,


    Can you help me please? I am having a problem with the
encryption/decryption of words with the Irish fada in them. The Irish
fada is like this: áéíóú/ÁÉÍÓÚ. It's kind of like the French
grave...

    Anyway when I run encryption on a plaintext word like:

RÍÓS NÁ RÚN

I get the following:

UKFzsStlitpd/QhEjqm0eQA=

    However, when I decrypt it I get the following:

RÍÃ"S NÁ RÚN


    As you can see it does not match the original plaintext. This is weird
- no? I'm confused - I was expecting the same original plaintext.
    Can anyone help me please? I have the encryption/decryprion code
below. I pulled it off the net. I would greatly appreciate any
suggestions/commends/omprovements. I want to get the original plaintext
when I decrypt - that's the naturte of the problem... please help me!



******* ENCRYPTION STUFF *******


    Public Shared Function EncryptString(ByVal AString As String) As
String
        If AString = String.Empty Then
            Return AString
        Else
            Dim encryptedData() As Byte
            Dim dataStream As MemoryStream


            Dim encryptor As ICryptoTransform
            encryptor = mProvider.CreateEncryptor()


            Try
                dataStream = New MemoryStream


                Dim encryptedStream As CryptoStream
                Try
                    'Create the encrypted stream
                    encryptedStream = New CryptoStream(dataStream,
encryptor, CryptoStreamMode.Write)


                    Dim theWriter As StreamWriter
                    Try
                        'Write the string to memory via the encryption
algorithm
                        theWriter = New StreamWriter(encryptedStream)
                        'Write the string to the memory stream
                        theWriter.Write(AString)


                        'End the writing
                        theWriter.Flush()
                        encryptedStream.FlushFinalBlock()


                        'Position back at start
                        dataStream.Position = 0


                        'Create area for data
                        ReDim encryptedData(CInt(dataStream.Length))


                        'Read data from memory
                        dataStream.Read(encryptedData, 0,
CInt(dataStream.Length))


                        'Convert to String
                        Return Convert.ToBase64String(encryptedData, 0,
encryptedData.Length)
                    Finally
                        theWriter.Close()
                    End Try
                Finally
                    encryptedStream.Close()
                End Try
            Finally
                dataStream.Close()
            End Try
        End If
    End Function



******* DECRYPTION STUFF *******


    Public Shared Function DecryptString(ByVal AString As String) As
String
        If AString = String.Empty Then
            Return AString
        Else
            Dim encryptedData() As Byte
            Dim dataStream As MemoryStream
            Dim encryptedStream As CryptoStream
            Dim strLen As Integer


            'Get the byte data
            encryptedData = Convert.FromBase64String(AString)


            Try
                dataStream = New MemoryStream
                Try
                    'Create decryptor and stream
                    Dim decryptor As ICryptoTransform
                    decryptor = mProvider.CreateDecryptor()
                    encryptedStream = New CryptoStream(dataStream,
decryptor, CryptoStreamMode.Write)


                    'Write the decrypted data to the memory stream
                    encryptedStream.Write(encryptedData, 0,
encryptedData.Length - 1)
                    encryptedStream.FlushFinalBlock()


                    'Position back at start
                    dataStream.Position = 0


                    'Determine length of decrypted string
                    strLen = CInt(dataStream.Length)


                    'Create area for data
                    ReDim encryptedData(strLen - 1)


                    'Read decrypted data to byte()
                    dataStream.Read(encryptedData, 0, strLen)


                    'Construct string from byte()
                    Dim retStr As String


                    Dim i As Integer
                    For i = 0 To strLen - 1
                        retStr += Chr(encryptedData(i))
                    Next


                    'Return result
                    Return retStr
                Finally
                    encryptedStream.Close()
                End Try
            Finally
                dataStream.Close()
            End Try
        End If
    End Function

Author
17 Jan 2006 4:39 PM
Larry Lard
almu***@altavista.com wrote:
> Hi everyone,
>
>
>     Can you help me please? I am having a problem with the
> encryption/decryption of words with the Irish fada in them. The Irish
> fada is like this: áéíóú/ÁÉÍÓÚ. It's kind of like the French
> grave...

The French acute, but we get it :)

>
>     Anyway when I run encryption on a plaintext word like:
>
> RÍÓS NÁ RÚN
>
> I get the following:
>
> UKFzsStlitpd/QhEjqm0eQA=
>
>     However, when I decrypt it I get the following:
>
> RÍÃ"S NÁ RÚN

Almost immediately I suspect a problem with encoding. We shall see if I
am right...

>     As you can see it does not match the original plaintext. This is weird
> - no? I'm confused - I was expecting the same original plaintext.
>     Can anyone help me please? I have the encryption/decryprion code
> below. I pulled it off the net. I would greatly appreciate any
> suggestions/commends/omprovements. I want to get the original plaintext
> when I decrypt - that's the naturte of the problem... please help me!

[code snipped]

Your source omits to mention what type of CSP mProvider is, but I
suspect it doesn't matter. These are the interesting parts:

>     Public Shared Function EncryptString(ByVal AString As String) As
> String
....
>                     Dim theWriter As StreamWriter
>                     Try
>                         'Write the string to memory via the encryption
> algorithm
>                         theWriter = New StreamWriter(encryptedStream)
>                         'Write the string to the memory stream
>                         theWriter.Write(AString)

and

>     Public Shared Function DecryptString(ByVal AString As String) As
> String
....
>                     'Construct string from byte()
>                     Dim retStr As String
>
>
>                     Dim i As Integer
>                     For i = 0 To strLen - 1
>                         retStr += Chr(encryptedData(i))
>                     Next

Whenever we convert between bytes and characters, we must make sure to
think carefully about the *encoding*. For any byte value between 128
and 255, the character mapped to will depend on the encoding; to get
correct roundtrip results, we must be sure to use the same encoding
both ways.

When you write your input string to the cryptostream, your StreamWriter
(as per the docs) defaults to UTF8Encoding. But when you read the bytes
back and convert back to a string, you use the legacy Chr() function,
which uses the current thread's default ANSI code page, which is a
different encoding than UTF8. Hence the difference in output from
input.

The quick fix is to use UTF8 on the way out as well as the way in:
replace the For loop in the above snippet from Decrypt with

retStr = System.Text.Encoding.UTF8.GetString(encryptedData)

and you're done.


The more enlightened  (but longer) path is to revise the code to have a
better distinction between character data and byte data. I realise it's
not your code but understanding is always worthwhile :)

To that end, ideally I would like to see the input string explicitly
converted to a byte() (with an explicit encoding), and that byte()
written to the CryptoStream; rather than (as at present) the character
-> byte conversion being hidden in the default behaviour of a
StreamWriter. Indeed, StreamWriter is meant for character data, but
encryption is done on byte data; this is the warning flag that
something is wrong.

I am sure you will be happy with just the quick fix, however :)

--
Larry Lard
Replies to group please
Author
17 Jan 2006 5:53 PM
almurph
Larry - merci beaucoup mon ami!

Perfect - its working - that a million mate!

Al.
The happy enlightened one.