簡體   English   中英

.NET中的對稱加密/解密

[英]Symmetric encrypt/decrypt in .NET

我正在使用C#中的對稱加密/解密例程。 我知道之前有關於這個主題的一些問題,但大多數答案似乎是關於加密的哲學,而不是給出實際的代碼。

更新:我真的很想看到一些代碼,而不僅僅是鏈接。 非常感謝!

查看本頁底部的示例代碼。

在此復制粘貼:

int Rfc2898KeygenIterations= 100;
int AesKeySizeInBits = 128;
String Password = "VerySecret!";
byte[] Salt = new byte[16];
System.Random rnd = new System.Random(); 
rnd.NextBytes(Salt);
byte[] rawPlaintext = System.Text.Encoding.Unicode.GetBytes("This is all clear now!");
byte[] cipherText= null;
byte[] plainText= null;
using (Aes aes = new AesManaged())
{
    aes.Padding = PaddingMode.PKCS7;
    aes.KeySize = AesKeySizeInBits;
    int KeyStrengthInBytes= aes.KeySize/8;
    System.Security.Cryptography.Rfc2898DeriveBytes rfc2898 =
        new System.Security.Cryptography.Rfc2898DeriveBytes(Password, Salt, Rfc2898KeygenIterations);
    aes.Key = rfc2898.GetBytes(KeyStrengthInBytes);
    aes.IV = rfc2898.GetBytes(KeyStrengthInBytes);
    using (MemoryStream ms = new MemoryStream())
    {
        using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
        {
            cs.Write(rawPlaintext, 0, rawPlaintext.Length);
        }
        cipherText= ms.ToArray();
    }

    using (MemoryStream ms = new MemoryStream())
    {
        using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
        {
            cs.Write(cipherText, 0, cipherText.Length);
        }
        plainText = ms.ToArray();
    }
}
string s = System.Text.Encoding.Unicode.GetString(plainText);
Console.WriteLine(s);

這是我在VB.NET論壇上找到並轉換為C#的簡單解決方案。 它確實幫助我更好地理解了這個主題。

// Shamelessly lifted from http://discuss.itacumens.com/index.php?topic=62872.0, 
// then converted to C# (http://www.developerfusion.com/tools/convert/vb-to-csharp/) and
// changed where necessary.
public class Encryptor
{
    private static SymmetricAlgorithm _cryptoService = new TripleDESCryptoServiceProvider(); 
    // maybe use AesCryptoServiceProvider instead?

    // vector and key have to match between encryption and decryption
    public static string Encrypt(string text, byte[] key, byte[] vector)
    {
        return Transform(text, _cryptoService.CreateEncryptor(key, vector));
    }

    // vector and key have to match between encryption and decryption
    public static string Decrypt(string text, byte[] key, byte[] vector)
    {
        return Transform(text, _cryptoService.CreateDecryptor(key, vector));
    }

    private static string Transform(string text, ICryptoTransform cryptoTransform)
    {
        MemoryStream stream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(stream, cryptoTransform, CryptoStreamMode.Write);

        byte[] input = Encoding.Default.GetBytes(text);

        cryptoStream.Write(input, 0, input.Length);
        cryptoStream.FlushFinalBlock();

        return Encoding.Default.GetString(stream.ToArray());
    }
}

好吧,首先,鍵不是字符串,鍵是二進制blob。 PlainText是相同的,它實際上不是文本,它也是二進制blob。

當然,您現在可以使用Encoding.UTF8.GetBytes(message)將字符串轉換為字節數組,但是當來回轉換鍵時,它通常會使用Convert.ToBase64StringConvert.FromBase64String

不要忘記分組密碼還需要一個東西,初始化向量,所以你的方法簽名應該是

byte[] Encrypt(byte[] plainText, byte[] key, byte[] iv)

byte[] Decrypt(byte[] cipherText, byte[] key, byte[] iv)

密鑰和IV 必須是加密安全的隨機數 ,不要只鍵入它們,也不要使用C#的Random函數。 密鑰和IV的大小取決於所使用的密碼算法,並且可以通過類的屬性訪問。

要生成CSRPNG,您可以執行類似的操作

RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] key = new byte[algorithm.KeySizeValue / 8];
rng.GetBytes(key);
byte[] iv = new byte[algorithm.BlockSizeValue / 8];
rng.GetBytes(iv);

您還可以使用Rfc2898DeriveBytes類從密碼和salt派生密鑰和IV,但鹽也應該是加密安全的隨機數。 您還應該注意,在創建對稱算法時,會為您生成安全密鑰和IV。

這樣,您就可以為文本選擇正確的編碼,無論是UTF8,ASCII還是其他。 鏈接有足夠的樣本,所以在這里切割和粘貼是相當無意義的。

首先使用您選擇的編碼將文本,鍵和初始化向量轉換為字節。 然后使用三重DES提供程序,如下所示:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledes.aspx

如果您認為三重DES過於老派,或者其他什么,那么也可以使用AES。

出於好奇,您打算如何傳達秘密密鑰?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM