如何在c#中加密和解密字符串?


当前回答

为了简单起见,我为自己做了这个函数,用于非加密目的:用你的密码替换“yourpassphrase”…

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

 namespace My
{
    public class strCrypto
    {
        // This constant string is used as a "salt" value for the PasswordDeriveBytes function calls.
    // This size of the IV (in bytes) must = (keysize / 8).  Default keysize is 256, so the IV must be
    // 32 bytes long.  Using a 16 character string here gives us 32 bytes when converted to a byte array.
    private const string initVector = "r5dm5fgm24mfhfku";
    private const string passPhrase = "yourpassphrase"; // email password encryption password

    // This constant is used to determine the keysize of the encryption algorithm.
    private const int keysize = 256;

    public static string encryptString(string plainText)
    {
        //if the plaintext  is empty or null string just return an empty string
        if (plainText == "" || plainText == null )
        {
            return "";
        }

        byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
        byte[] keyBytes = password.GetBytes(keysize / 8);
        RijndaelManaged symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
        cryptoStream.FlushFinalBlock();
        byte[] cipherTextBytes = memoryStream.ToArray();
        memoryStream.Close();
        cryptoStream.Close();
        return Convert.ToBase64String(cipherTextBytes);
    }

    public static string decryptString(string cipherText)
    {
        //if the ciphertext is empty or null string just return an empty string
        if (cipherText == "" || cipherText == null )
        {
            return "";
        }

        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
        byte[] keyBytes = password.GetBytes(keysize / 8);
        RijndaelManaged symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;
        ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
        MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
        CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
        byte[] plainTextBytes = new byte[cipherTextBytes.Length];
        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
        memoryStream.Close();
        cryptoStream.Close();
        return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
    }


}

}

其他回答

下面是一个使用RSA的例子。

重要:使用RSA加密KeySize - MinimumPadding加密的数据大小是有限制的。例如256字节(假设2048位密钥)- 42字节(最小OEAP填充)= 214字节(最大明文大小)

用RSA密钥替换your_rsa_key。

var provider = new System.Security.Cryptography.RSACryptoServiceProvider();
provider.ImportParameters(your_rsa_key);

var encryptedBytes = provider.Encrypt(
    System.Text.Encoding.UTF8.GetBytes("Hello World!"), true);

string decryptedTest = System.Text.Encoding.UTF8.GetString(
    provider.Decrypt(encryptedBytes, true));

更多信息,请访问MSDN - RSACryptoServiceProvider

我有一个名为X509Crypto的开源项目,它利用证书来加密和解密字符串。它很容易使用。下面是一个如何使用它的例子:

1. 2 .使用X509Crypto命令行生成新的加密证书和密钥对

>x509crypto.exe
X509Crypto> makecert -context user -keysize medium -alias myvault

Certificate with thumbprint B31FE7E7AE5229F8186782742CF579197FA859FD was added to X509Alias "myvault" in the user X509Context

X509Crypto>

2. 使用Encrypt CLI命令向新的X509Alias添加一个秘密

X509Crypto> encrypt -text -alias myvault -context user -secret apikey -in "80EAF03248965AC2B78090"

Secret apikey has been added to X509Alias myvault in the user X509Context

X509Crypto>

3.在程序中引用该秘密

一旦你建立了一个X509Alias并添加了你的秘密,在你的程序中使用Org检索它们是很简单的。X509Crypto nuget包安装:

using Org.X509Crypto;

namespace SampleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var Alias = new X509Alias(@"myvault", X509Context.UserReadOnly);
            var apiKey = Alias.RecoverSecret(@"apikey");
        }
    }
}

免责声明:此解决方案只能用于未公开的静态数据(例如配置文件或DB)。只有在这种情况下,快速和肮脏的解决方案才能被认为比@jbtule的解决方案更好,因为它的维护更低。

原来的帖子: 我发现jbtule的答案对于一个快速和肮脏的安全AES字符串加密有点复杂,Brett的答案有一个错误,初始化向量是一个固定的值,使它容易受到填充攻击,所以我修复了Brett的代码,并添加了一个随机IV,添加到chitered字符串,创建一个不同的加密值,每个加密相同的值:

加密:

public static string Encrypt(string clearText)
{            
    byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
    using (Aes encryptor = Aes.Create())
    {
        byte[] IV = new byte[15];
        rand.NextBytes(IV);
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV);
        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV = pdb.GetBytes(16);
        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(clearBytes, 0, clearBytes.Length);
                cs.Close();
            }
            clearText = Convert.ToBase64String(IV) + Convert.ToBase64String(ms.ToArray());
        }
    }
    return clearText;
}

解密:

public static string Decrypt(string cipherText)
{
    byte[] IV = Convert.FromBase64String(cipherText.Substring(0, 20));
    cipherText = cipherText.Substring(20).Replace(" ", "+");
    byte[] cipherBytes = Convert.FromBase64String(cipherText);
    using (Aes encryptor = Aes.Create())
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV);
        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV = pdb.GetBytes(16);
        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(cipherBytes, 0, cipherBytes.Length);
                cs.Close();
            }
            cipherText = Encoding.Unicode.GetString(ms.ToArray());
        }
    }
    return cipherText;
}

将EncryptionKey替换为您的密钥。 在我的实现中,密钥被保存在配置文件(web.config\app.config)中,因为您不应该将其硬编码保存。配置文件也应该加密,这样密钥就不会被保存为明文。

protected static string _Key = "";
protected static string EncryptionKey
{
    get
    {
        if (String.IsNullOrEmpty(_Key))
        {
            _Key = ConfigurationManager.AppSettings["AESKey"].ToString();
        }

        return _Key;
    }
}

加密

public string EncryptString(string inputString)
{
    MemoryStream memStream = null;
    try
    {
        byte[] key = { };
        byte[] IV = { 12, 21, 43, 17, 57, 35, 67, 27 };
        string encryptKey = "aXb2uy4z"; // MUST be 8 characters
        key = Encoding.UTF8.GetBytes(encryptKey);
        byte[] byteInput = Encoding.UTF8.GetBytes(inputString);
        DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
        memStream = new MemoryStream();
        ICryptoTransform transform = provider.CreateEncryptor(key, IV);
        CryptoStream cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write);
        cryptoStream.Write(byteInput, 0, byteInput.Length);
        cryptoStream.FlushFinalBlock();
    }
    catch (Exception ex)
    {
        Response.Write(ex.Message);
    }
    return Convert.ToBase64String(memStream.ToArray());
}

解密:

public string DecryptString(string inputString)
{
    MemoryStream memStream = null;
    try
    {
        byte[] key = { };
        byte[] IV = { 12, 21, 43, 17, 57, 35, 67, 27 };
        string encryptKey = "aXb2uy4z"; // MUST be 8 characters
        key = Encoding.UTF8.GetBytes(encryptKey);
        byte[] byteInput = new byte[inputString.Length];
        byteInput = Convert.FromBase64String(inputString);
        DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
        memStream = new MemoryStream();
        ICryptoTransform transform = provider.CreateDecryptor(key, IV);
        CryptoStream cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write);
        cryptoStream.Write(byteInput, 0, byteInput.Length);
        cryptoStream.FlushFinalBlock();
    }
    catch (Exception ex)
    {
        Response.Write(ex.Message);
    }

    Encoding encoding1 = Encoding.UTF8;
    return encoding1.GetString(memStream.ToArray());
}

参考c#中加密和解密字符串,我找到了一个很好的解决方案:

static readonly string PasswordHash = "P@@Sw0rd";
static readonly string SaltKey = "S@LT&KEY";
static readonly string VIKey = "@1B2c3D4e5F6g7H8";

对于加密

public static string Encrypt(string plainText)
{
    byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

    byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
    var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
    var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));

    byte[] cipherTextBytes;

    using (var memoryStream = new MemoryStream())
    {
        using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
        {
            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
            cryptoStream.FlushFinalBlock();
            cipherTextBytes = memoryStream.ToArray();
            cryptoStream.Close();
        }
        memoryStream.Close();
    }
    return Convert.ToBase64String(cipherTextBytes);
}

对解密

public static string Decrypt(string encryptedText)
{
    byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
    byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
    var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };

    var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
    var memoryStream = new MemoryStream(cipherTextBytes);
    var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
    byte[] plainTextBytes = new byte[cipherTextBytes.Length];

    int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
    memoryStream.Close();
    cryptoStream.Close();
    return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());
}