我正在为一些数据寻找非常简单的混淆(比如加密和解密,但不一定安全)功能。这不是关键任务。我需要一些东西来保持诚实的人诚实,但比ROT13或Base64更强大一点。

我更喜欢一些已经包含在. net框架2.0中的东西,这样我就不必担心任何外部依赖。

我真的不想在公钥/私钥等方面浪费时间。我不太懂加密,但我知道我写的任何东西都是没有价值的……事实上,我可能会把数学搞砸,让它变得微不足道。


当前回答

如果你只是想要简单的加密(即,一个坚定的破解者可能会破解,但会锁定大多数普通用户),只需选择两个长度相等的密码短语,例如:

deoxyribonucleicacid
while (x>0) { x-- };

和xor你的数据与他们(循环密码短语,如果需要)(a)。例如:

1111-2222-3333-4444-5555-6666-7777
deoxyribonucleicaciddeoxyribonucle
while (x>0) { x-- };while (x>0) { 

搜索二进制文件的人很可能认为DNA字符串是一个密钥,但他们不太可能认为C代码是用二进制文件保存的未初始化内存。


(a)请记住,这是非常简单的加密,根据某些定义,可能根本不被认为是加密(因为加密的目的是防止未经授权的访问,而不仅仅是使其更加困难)。当然,即使是最强的加密也不安全因为有人拿着钢管站在钥匙持有人旁边。

正如第一句所述,这是一种让随意的攻击者变得足够困难的方法,他们会继续前进。这类似于防止入室盗窃——你不需要让它变得坚不可摧,你只需要让它比隔壁的房子不那么坚不可摧:-)

其他回答

命名空间System.Security.Cryptography包含TripleDESCryptoServiceProvider类和RijndaelManaged类

不要忘记添加对系统的引用。安全大会。

我想发布我的解决方案,因为上面的解决方案都不像我的那么简单。让我知道你的想法:

 // This will return an encrypted string based on the unencrypted parameter
 public static string Encrypt(this string DecryptedValue)
 {
      HttpServerUtility.UrlTokenEncode(MachineKey.Protect(Encoding.UTF8.GetBytes(DecryptedValue.Trim())));
 }

 // This will return an unencrypted string based on the parameter
 public static string Decrypt(this string EncryptedValue)
 {
      Encoding.UTF8.GetString(MachineKey.Unprotect(HttpServerUtility.UrlTokenDecode(EncryptedValue)));
 }

可选

这里假设用于加密该值的服务器的MachineKey与用于解密该值的MachineKey相同。如果需要,您可以在Web中指定一个静态MachineKey。配置,使您的应用程序可以解密/加密数据,而不管它在哪里运行(例如开发还是生产服务器)。您可以按照这些说明生成一个静态机器密钥。

这里的其他答案都可以,但AES是一种更安全、最新的加密算法。这是我几年前获得的一个类,用于执行AES加密,随着时间的推移,我已经对其进行了修改,以使其对web应用程序(例如,g)更加友好。我已经构建了加密/解密方法,用于url友好的字符串)。它还有处理字节数组的方法。

注意:你应该在Key(32字节)和Vector(16字节)数组中使用不同的值!您不会希望别人通过假设您按原样使用此代码来找出您的密钥!你所要做的就是改变Key和Vector数组中的一些数字(必须是<= 255)(我在Vector数组中留下了一个无效的值,以确保你这样做…)你可以使用https://www.random.org/bytes/生成一个新的集合:

生成密钥 生成向量

使用它很简单:只需实例化类,然后调用(通常)EncryptToString(string StringToEncrypt)和DecryptString(string StringToDecrypt)作为方法。一旦有了这个类,就不会更容易(或更安全)了。


using System;
using System.Data;
using System.Security.Cryptography;
using System.IO;


public class SimpleAES
{
    // Change these keys
    private byte[] Key = __Replace_Me__({ 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 });

    // a hardcoded IV should not be used for production AES-CBC code
    // IVs should be unpredictable per ciphertext
    private byte[] Vector = __Replace_Me__({ 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 2521, 112, 79, 32, 114, 156 });


    private ICryptoTransform EncryptorTransform, DecryptorTransform;
    private System.Text.UTF8Encoding UTFEncoder;

    public SimpleAES()
    {
        //This is our encryption method
        RijndaelManaged rm = new RijndaelManaged();

        //Create an encryptor and a decryptor using our encryption method, key, and vector.
        EncryptorTransform = rm.CreateEncryptor(this.Key, this.Vector);
        DecryptorTransform = rm.CreateDecryptor(this.Key, this.Vector);

        //Used to translate bytes to text and vice versa
        UTFEncoder = new System.Text.UTF8Encoding();
    }

    /// -------------- Two Utility Methods (not used but may be useful) -----------
    /// Generates an encryption key.
    static public byte[] GenerateEncryptionKey()
    {
        //Generate a Key.
        RijndaelManaged rm = new RijndaelManaged();
        rm.GenerateKey();
        return rm.Key;
    }

    /// Generates a unique encryption vector
    static public byte[] GenerateEncryptionVector()
    {
        //Generate a Vector
        RijndaelManaged rm = new RijndaelManaged();
        rm.GenerateIV();
        return rm.IV;
    }


    /// ----------- The commonly used methods ------------------------------    
    /// Encrypt some text and return a string suitable for passing in a URL.
    public string EncryptToString(string TextValue)
    {
        return ByteArrToString(Encrypt(TextValue));
    }

    /// Encrypt some text and return an encrypted byte array.
    public byte[] Encrypt(string TextValue)
    {
        //Translates our text value into a byte array.
        Byte[] bytes = UTFEncoder.GetBytes(TextValue);

        //Used to stream the data in and out of the CryptoStream.
        MemoryStream memoryStream = new MemoryStream();

        /*
         * We will have to write the unencrypted bytes to the stream,
         * then read the encrypted result back from the stream.
         */
        #region Write the decrypted value to the encryption stream
        CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write);
        cs.Write(bytes, 0, bytes.Length);
        cs.FlushFinalBlock();
        #endregion

        #region Read encrypted value back out of the stream
        memoryStream.Position = 0;
        byte[] encrypted = new byte[memoryStream.Length];
        memoryStream.Read(encrypted, 0, encrypted.Length);
        #endregion

        //Clean up.
        cs.Close();
        memoryStream.Close();

        return encrypted;
    }

    /// The other side: Decryption methods
    public string DecryptString(string EncryptedString)
    {
        return Decrypt(StrToByteArray(EncryptedString));
    }

    /// Decryption when working with byte arrays.    
    public string Decrypt(byte[] EncryptedValue)
    {
        #region Write the encrypted value to the decryption stream
        MemoryStream encryptedStream = new MemoryStream();
        CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write);
        decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length);
        decryptStream.FlushFinalBlock();
        #endregion

        #region Read the decrypted value from the stream.
        encryptedStream.Position = 0;
        Byte[] decryptedBytes = new Byte[encryptedStream.Length];
        encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length);
        encryptedStream.Close();
        #endregion
        return UTFEncoder.GetString(decryptedBytes);
    }

    /// Convert a string to a byte array.  NOTE: Normally we'd create a Byte Array from a string using an ASCII encoding (like so).
    //      System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
    //      return encoding.GetBytes(str);
    // However, this results in character values that cannot be passed in a URL.  So, instead, I just
    // lay out all of the byte values in a long string of numbers (three per - must pad numbers less than 100).
    public byte[] StrToByteArray(string str)
    {
        if (str.Length == 0)
            throw new Exception("Invalid string value in StrToByteArray");

        byte val;
        byte[] byteArr = new byte[str.Length / 3];
        int i = 0;
        int j = 0;
        do
        {
            val = byte.Parse(str.Substring(i, 3));
            byteArr[j++] = val;
            i += 3;
        }
        while (i < str.Length);
        return byteArr;
    }

    // Same comment as above.  Normally the conversion would use an ASCII encoding in the other direction:
    //      System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
    //      return enc.GetString(byteArr);    
    public string ByteArrToString(byte[] byteArr)
    {
        byte val;
        string tempStr = "";
        for (int i = 0; i <= byteArr.GetUpperBound(0); i++)
        {
            val = byteArr[i];
            if (val < (byte)10)
                tempStr += "00" + val.ToString();
            else if (val < (byte)100)
                tempStr += "0" + val.ToString();
            else
                tempStr += val.ToString();
        }
        return tempStr;
    }
}

在System.Security.Cryptography中使用TripleDESCryptoServiceProvider:

public static class CryptoHelper
{
    private const string Key = "MyHashString";
    private static TripleDESCryptoServiceProvider GetCryproProvider()
    {
        var md5 = new MD5CryptoServiceProvider();
        var key = md5.ComputeHash(Encoding.UTF8.GetBytes(Key));
        return new TripleDESCryptoServiceProvider() { Key = key, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 };
    }

    public static string Encrypt(string plainString)
    {
        var data = Encoding.UTF8.GetBytes(plainString);
        var tripleDes = GetCryproProvider();
        var transform = tripleDes.CreateEncryptor();
        var resultsByteArray = transform.TransformFinalBlock(data, 0, data.Length);
        return Convert.ToBase64String(resultsByteArray);
    }

    public static string Decrypt(string encryptedString)
    {
        var data = Convert.FromBase64String(encryptedString);
        var tripleDes = GetCryproProvider();
        var transform = tripleDes.CreateDecryptor();
        var resultsByteArray = transform.TransformFinalBlock(data, 0, data.Length);
        return Encoding.UTF8.GetString(resultsByteArray);
    }
}

多年后,我回来对他们说:不要这样做!看XOR加密有什么问题?获取详细信息。

一种非常简单的双向加密是异或加密。

Come up with a password. Let's have it be mypass. Convert the password into binary (according to ASCII). The password becomes 01101101 01111001 01110000 01100001 01110011 01110011. Take the message you want to encode. Convert that into binary, also. Look at the length of the message. If the message length is 400 bytes, turn the password into a 400 byte string by repeating it over and over again. It would become 01101101 01111001 01110000 01100001 01110011 01110011 01101101 01111001 01110000 01100001 01110011 01110011 01101101 01111001 01110000 01100001 01110011 01110011... (or mypassmypassmypass...) XOR the message with the long password. Send the result. Another time, XOR the encrypted message with the same password (mypassmypassmypass...). There's your message!