Krumelur
Krumelur

Reputation: 33048

Easy way to encrypt/obfuscate a byte array using a secret in .NET?

I'm looking for a way to encrypt/obfuscate (and of course decrypt/deobfuscate) an array of byte using .NET 3.5.

Basically:

byte[] aMixedUp = Encrypt(aMyByteData, "THIS IS THE SECRET KEY USED TO ENCRYPT");

and on the other side:

byte[] aDecrypted = Decrypt(aMixedUp, "THIS IS THE SECRET KEY USED TO ENCRYPT");

It does not have to be bullet proof. The idea is just to prevent users from directly seeing what's in the bytes in case they map to ASCII but it should be better then ROT13.

Is there something in the .NET libraries I can easily use?

Upvotes: 9

Views: 12783

Answers (5)

Blorgbeard
Blorgbeard

Reputation: 103467

Here's some code I wrote to encrypt/decrypt a string. The encrypted string is Base64 encoded for ease of serialization to XML, etc. You could easily convert this code to work directly with byte arrays instead of strings.

/// <summary>
/// Create and initialize a crypto algorithm.
/// </summary>
/// <param name="password">The password.</param>
private static SymmetricAlgorithm GetAlgorithm(string password)
{
    var algorithm = Rijndael.Create();
    var rdb = new Rfc2898DeriveBytes(password, new byte[] {
        0x53,0x6f,0x64,0x69,0x75,0x6d,0x20,             // salty goodness
        0x43,0x68,0x6c,0x6f,0x72,0x69,0x64,0x65
    });
    algorithm.Padding = PaddingMode.ISO10126;
    algorithm.Key = rdb.GetBytes(32);
    algorithm.IV = rdb.GetBytes(16);
    return algorithm;
}


/// <summary>
/// Encrypts a string with a given password.
/// </summary>
/// <param name="clearText">The clear text.</param>
/// <param name="password">The password.</param>
public static string EncryptString(string clearText, string password)
{
    var algorithm = GetAlgorithm(password);
    var encryptor = algorithm.CreateEncryptor();
    var clearBytes = Encoding.Unicode.GetBytes(clearText);
    using (var ms = new MemoryStream())
    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
    {
        cs.Write(clearBytes, 0, clearBytes.Length);
        cs.Close();
        return Convert.ToBase64String(ms.ToArray());
    }
}

/// <summary>
/// Decrypts a string using a given password.
/// </summary>
/// <param name="cipherText">The cipher text.</param>
/// <param name="password">The password.</param>
public static string DecryptString(string cipherText, string password)
{
    var algorithm = GetAlgorithm(password);
    var decryptor = algorithm.CreateDecryptor();
    var cipherBytes = Convert.FromBase64String(cipherText);
    using (var ms = new MemoryStream())
    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
    {
        cs.Write(cipherBytes, 0, cipherBytes.Length);
        cs.Close();
        return Encoding.Unicode.GetString(ms.ToArray());
    }
}

Upvotes: 8

Ali
Ali

Reputation: 12674

If you don't need encryption, you can just convert everything to HEX or Base 64 or something of that sort, effectively it'll make it impossible to read unless someone is really dedicated. Here is a link that shows how in .NET

Upvotes: 0

lowds
lowds

Reputation: 1135

The following is a sample of code that uses the Rijndael class from the .NET framework to encrypt and decrypt an array of bytes; obviously this class can be substituted for which ever suits you the best.

You would just need to define the KEY and IV properties and get them from somewhere (encrypted section of the application config file for example).

    private static byte[] EncryptBytes(IEnumerable<byte> bytes)
    {
        //The ICryptoTransform is created for each call to this method as the MSDN documentation indicates that the public methods may not be thread-safe and so we cannot hold a static reference to an instance
        using (var r = Rijndael.Create())
        {
            using (var encryptor = r.CreateEncryptor(KEY, IV))
            {
                return Transform(bytes, encryptor);
            }
        }
    }

    private static byte[] DecryptBytes(IEnumerable<byte> bytes)
    {
        //The ICryptoTransform is created for each call to this method as the MSDN documentation indicates that the public methods may not be thread-safe and so we cannot hold a static reference to an instance
        using (var r = Rijndael.Create())
        {
            using (var decryptor = r.CreateDecryptor(KEY, IV))
            {
                return Transform(bytes, decryptor);
            }
        }
    }

    private static byte[] Transform(IEnumerable<byte> bytes, ICryptoTransform transform)
    {
        using (var stream = new MemoryStream())
        {
            using (var cryptoStream = new CryptoStream(stream, transform, CryptoStreamMode.Write))
            {
                foreach (var b in bytes)
                    cryptoStream.WriteByte(b);
            }

            return stream.ToArray();
        }
    }

Upvotes: 4

EKS
EKS

Reputation: 5623

Symmetric-key algorithm would be the easyest way to do this, you can find them in the .NET framework.

But be aware a hacker can "easly" decompile your app and find the encryption key. Depending on your senario you can use a public/private key system. You at least can control who can encrypt the byte array.

Upvotes: 3

CheeZe5
CheeZe5

Reputation: 995

There are all kinds of fun things in the cryptography namespace.

Upvotes: 1

Related Questions