Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / February 2007

Tip: Looking for answers? Try searching our database.

How to decrypt a string?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Ralph Moritz - 08 Feb 2007 09:01 GMT
Hi group,

I'm trying to encrypt & then decrypt a string using symmetric
encryption. The encryption seems to work fine, but when trying to
decrypt, I get a System.IndexOutOfRangeException. Please would someone
be kind enough to point out my mistake? Please see my code (C++/CLI)
below.

TIA,
Ralph

System::String^ Quantum::Util::EncryptString(System::String^ str)
{
    using namespace System::IO;
    using namespace System::Security::Cryptography;

    MemoryStream^ ms = gcnew MemoryStream;
    RijndaelManaged^ rm = gcnew RijndaelManaged;
    CryptoStream^ cs = gcnew CryptoStream(ms, rm->CreateEncryptor(m_key, m_iv),
        CryptoStreamMode::Write);
    StreamWriter^ sw = gcnew StreamWriter(cs);
   
    try {
        sw->Write(str);
    } finally {
        sw->Close();
        cs->Close();
        ms->Close();
    }

    return System::Convert::ToBase64String(ms->ToArray());
}

System::String^ Quantum::Util::DecryptString(System::String^ str)
{
    using namespace System::IO;
    using namespace System::Security::Cryptography;

    MemoryStream^ ms = gcnew MemoryStream;
    RijndaelManaged^ rm = gcnew RijndaelManaged;
    CryptoStream^ cs = gcnew CryptoStream(ms, rm->CreateDecryptor(m_key, m_iv),
        CryptoStreamMode::Read);
    StreamWriter^ sw = gcnew StreamWriter(ms);
    StreamReader^ sr = gcnew StreamReader(cs);

    System::String^ cleartext;
    try {
        array<System::Byte>^ bytes = System::Convert::FromBase64String(str);
        sw->Write(bytes);
        cleartext = sr->ReadToEnd();
    } finally {
        sw->Close();
        sr->Close();
        cs->Close();
        ms->Close();
    }

    return cleartext;
}
Kevin Spencer - 08 Feb 2007 12:30 GMT
To use the CryptoStream class, you create an instance of the class from a
stream, as you have done. Then you use a StreamWriter to write your input to
the CryptoStream, which you have also done. This writes the encrypted string
to the stream you initialized the CryptoStream with. At this point, your
MemoryStream contains a string; it is a stream of text. So, rather than
using the Convert.ToBase64String method, just create a StreamReader to read
the string from your MemoryStream.

Signature

HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

The shortest distance between 2 points is a curve.

> Hi group,
>
[quoted text clipped - 57 lines]
> return cleartext;
> }
Ralph Moritz - 08 Feb 2007 13:34 GMT
> To use the CryptoStream class, you create an instance of the class from a
> stream, as you have done. Then you use a StreamWriter to write your input to
[quoted text clipped - 3 lines]
> using the Convert.ToBase64String method, just create a StreamReader to read
> the string from your MemoryStream.

That won't work, I'm afraid. My program needs to encrypt a string and
write it to a config file. When the program starts up, it checks for
the existence of a config file, and tries to read the encrypted
connection string from the file. The problem I discovered early on is
that mixing text and binary data is a BAD IDEA, so I have to Base64
encode the string before writing it to the config file. Logically
then, it follows that I need to Base64 decode the string before
attempting to decrypt it.
Kevin Spencer - 08 Feb 2007 16:09 GMT
Not at all. The MemoryStream already contains a string. In essence, you are
converting a string to another string.

Signature

HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

The shortest distance between 2 points is a curve.

>> To use the CryptoStream class, you create an instance of the class from a
>> stream, as you have done. Then you use a StreamWriter to write your input
[quoted text clipped - 15 lines]
> then, it follows that I need to Base64 decode the string before
> attempting to decrypt it.
Jon Skeet [C# MVP] - 08 Feb 2007 19:27 GMT
> Not at all. The MemoryStream already contains a string. In essence, you are
> converting a string to another string.

No. Encryption works on binary data, and it's not safe to treat
arbitrary binary data as if it were valid text data.

The OP is quite right to convert the encrypted bytes into a string
using Base64 and then convert the Base64 data back into bytes before
decryption.

What he's doing wrong is using StreamWriter.Write(bytes) instead of
just writing the converted data directly into the MemoryStream.

The encryption is:
Plaintext String -> Encrypted bytes -> Base64

The decrypion should thus be:
Base64 -> Encrypted bytes -> Plaintext String

Currently it's

Base64 -> Encrypted bytes -> ToString() -> Plaintext String

The call to ToString() is in the StreamWriter.Write(object) call.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Kevin Spencer - 09 Feb 2007 11:03 GMT
Hi Jon,

In this case, it's not arbitrary data. It's a string. The methods are
strongly-typed to encrypt and decrypt string data.

Signature

HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

The shortest distance between 2 points is a curve.

>> Not at all. The MemoryStream already contains a string. In essence, you
>> are
[quoted text clipped - 21 lines]
>
> The call to ToString() is in the StreamWriter.Write(object) call.
Jon Skeet [C# MVP] - 09 Feb 2007 11:24 GMT
> In this case, it's not arbitrary data. It's a string. The methods are
> strongly-typed to encrypt and decrypt string data.

It starts off as a string, but encryption will turn it into arbitrary
binary data. An encrypted version of a UTF-8 string isn't necessarily
(and often won't be) a valid UTF-8 encoded string. Converting
encrypted data into a string just using Encoding.UTF8 (or the like) is
very, very likely to lose data. It's like trying to load up the
contents of a jpeg file as a string, pass that to someone else to
write out, and then expecting it to still load. It just won't work (in
the general case).

Base64 is absolutely the way to go here.

Jon
Kevin Spencer - 09 Feb 2007 21:44 GMT
I'll take your word for it, Jon. :-)

Signature

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

The shortest distance between 2 points is a curve.

>> In this case, it's not arbitrary data. It's a string. The methods are
>> strongly-typed to encrypt and decrypt string data.
[quoted text clipped - 11 lines]
>
> Jon

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.