"Helge Jensen" <helge.jensen@slog.dk> wrote in message
news:%23rEFj6$0FHA.3780@TK2MSFTNGP12.phx.gbl...[color=blue]
> SP wrote:
>[color=green][color=darkred]
>>>Is there Buid-In fuction in C# that Encrypt and Decrypt strings?
>>>i have a textbox which i'm writing into file, and i want to encrypt it
>>>before writing, i'm not looking for something fancy, just for a simple
>>>Encryption and Decryption function.[/color][/color]
>
> Find one at the bottom. The "MyChoiceOf..." functions reflect more or
> less arbitrary choices which I have made for the test -- the choices
> taken should be sufficient for most applications.
>
> Note that a more proper use of IV would be to generate it randomly and
> include the IV in clear in the encrypted text.
>
> Beware that cryptography is really hard to get right and the sligtest
> error often results in a complete compromise of the data thought to be
> protected.
>[color=green]
>> Try the following:[/color]
>
> There are several things I am not too happy about in that code:[/color]
It was one of those things that once it worked and it was being used then I
did not want to change it. You make some valid points and I do have some
comments and questions inline.
[color=blue]
> - It uses DES-encryption[/color]
Can you explain why DES is not the best choice.
[color=blue]
> - It is designed with the keys in the code[/color]
How can you decrypt without the keys in your code somewhere. I place the
keys in one place and they are encrypted by an obfuscator. How do you avoid
placing the keys in your code?
[color=blue]
> - It uses a constant IV[/color]
Is it better to use an encrypted and unknown IV or a random but known IV?
You suggested above to use a random IV and store it in clear text.
[color=blue]
> - It doesn't come with a test (I know, that's a cheap-shot ;)[/color]
I did not provide the unit tests. They are in a separate class. Of course it
is easy to test.
[color=blue]
> - It converts data, to and from Base64[/color]
Originally it was to be a license key so it may of needed to be typed in.
[color=blue]
> - It duplicates the code for creating the en/de-cryption keys[/color]
Because I do not provide the Encrypt function in the Release build, only the
Decrypt.
[color=blue]
> - It only works for strings with a valid ASCII-encoding
> - It only works for keys with a valid ASCII-encoding
> - It uses the ascii-encoding of key-strings as keys[/color]
I knew that the text going in was ASCII but do not want to change anything
at this point.[color=blue]
> - It uses a MemoryStream where it's not required[/color]
I thought the same at the time. I will look at your code to see how to
eliminate the MemoryStream.
Regards
SP.
[color=blue]
> Here is my shot at how to do it. note that it copies the IV and
> encrypted-string into a new byte[]. If you are reading/writing to a
> stream you can remove that, but you explicitly requested simplicity and
> the interface would be much more complicated if the cipher-text and IV
> is returned/passed seperatly.
>
> using System.Security.Cryptography;
> using System.Text;
>
> class CryptExample
> {
> public static void InitializeAlgorithm(string secret, HashAlgorithm h,
> SymmetricAlgorithm a)
> {
> byte[] b = System.Text.Encoding.UTF8.GetBytes(secret);
> h.TransformFinalBlock(b, 0, b.Length);
> byte[] secret_hashed = h.Hash;
> byte[] key = new byte[a.KeySize/8];
> System.Array.Copy(secret_hashed, 0, key, 0, key.Length);
> a.Key = key;
> }
> public static byte[] Encrypt(string s, SymmetricAlgorithm a)
> {
> byte[] b = Encoding.UTF8.GetBytes(s);
> a.GenerateIV();
> byte[] iv = a.IV;
> byte[] enc;
> using ( ICryptoTransform c = a.CreateEncryptor() )
> enc = c.TransformFinalBlock(b, 0, b.Length);
> byte[] all = new byte[iv.Length+enc.Length];
> System.Array.Copy(iv, 0, all, 0, iv.Length);
> System.Array.Copy(enc, 0, all, iv.Length, enc.Length);
> return all;
> }
> public static string Decrypt(byte[] bytes, int offset, int length,
> SymmetricAlgorithm a)
> {
> byte[] iv = new byte[a.BlockSize/8];
> System.Array.Copy(bytes, offset, iv, 0, iv.Length);
> a.IV = iv;
> using ( ICryptoTransform c = a.CreateDecryptor() )
> return Encoding.UTF8.GetString(c.TransformFinalBlock(byte s, offset
> + iv.Length, length - iv.Length));
> }
> public static SymmetricAlgorithm MyChoiceOfEncryptionAlgo()
> {
> SymmetricAlgorithm alg = Rijndael.Create();
> alg.Mode = CipherMode.CBC;
> alg.Padding = PaddingMode.PKCS7;
> alg.KeySize = 256;
> return alg;
> }
> public static HashAlgorithm MyChoiceOfHashAlgo() { return
> SHA512.Create(); }
> public static void Main()
> {
> string secret = "password";
> SymmetricAlgorithm enc_algo = MyChoiceOfEncryptionAlgo();
> SymmetricAlgorithm dec_algo = MyChoiceOfEncryptionAlgo();
>
> InitializeAlgorithm(secret, MyChoiceOfHashAlgo(), enc_algo);
> InitializeAlgorithm(secret, MyChoiceOfHashAlgo(), dec_algo);
>
> for ( int i = 0; i < 1000000; i = (3*i + 1) )
> {
> string msg = new string('a', i);
> byte[] enc = Encrypt(msg, enc_algo);
> string dec = Decrypt(enc, 0, enc.Length, dec_algo);
> if ( msg != dec )
> throw new CryptographicException(string.Format("Plain and
> decrypted did not match: {0}!={1}", msg, dec));
> }
> }
> }
>
>
> --
> Helge Jensen
> mailto:helge.jensen@slog.dk
> sip:helge.jensen@slog.dk
> -=> Sebastian cover-music:
http://ungdomshus.nu <=-[/color]