开发者

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?


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());
    }
}


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();
        }
    }


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.


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


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜