首頁 >後端開發 >C++ >如何使用RijndaelManed和密碼學API在C#中加密和解密字符串?

如何使用RijndaelManed和密碼學API在C#中加密和解密字符串?

Susan Sarandon
Susan Sarandon原創
2025-02-02 16:56:10183瀏覽

How to Encrypt and Decrypt Strings in C# Using RijndaelManaged and the Cryptography API?

C# 字符串加密和解密

在 C# 中,字符串加密和解密是數據保護的關鍵環節。讓我們探討兩種常用的方法:

1. 使用 RijndaelManaged 類

RijndaelManaged 類提供了流行的 AES(高級加密標準)算法的強大實現。以下是一個加密和解密字符串的示例:

<code class="language-csharp">using System.Security.Cryptography;
using System.Text;

public static class Crypto
{
    // 虽然应用程序特定的盐不是基于密码的加密的最佳实践,
    // 但只要它确实不常见,它可能足够安全。修改此答案还需要做很多工作。
    private static byte[] _salt = { ... };

    public static string Encrypt(string plainText, string sharedSecret)
    {
        // 从共享密钥和盐生成密钥
        Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);

        // 创建 RijndaelManaged 对象
        RijndaelManaged aesAlg = new RijndaelManaged();
        aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);

        // 加密数据
        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
        byte[] cipherText = null;

        using (MemoryStream msEncrypt = new MemoryStream())
        {
            // 添加 IV
            msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int));
            msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);

            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    // 将数据写入流
                    swEncrypt.Write(plainText);
                }
            }

            cipherText = msEncrypt.ToArray();
        }

        // 将加密的字节作为 base64 字符串返回
        return Convert.ToBase64String(cipherText);
    }

    public static string Decrypt(string cipherText, string sharedSecret)
    {
        // 从共享密钥和盐生成密钥
        Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);

        // 创建 RijndaelManaged 对象
        RijndaelManaged aesAlg = new RijndaelManaged();
        aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);

        // 解密数据
        ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
        byte[] plainText = null;

        using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText)))
        {
            // 从加密流中获取初始化向量
            aesAlg.IV = ReadByteArray(msDecrypt);

            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                {
                    // 从解密流中读取解密的字节
                    plainText = Encoding.UTF8.GetBytes(srDecrypt.ReadToEnd());
                }
            }
        }

        // 将解密的文本作为字符串返回
        return Encoding.UTF8.GetString(plainText);
    }

    // 读取流中字节数组的辅助方法
    private static byte[] ReadByteArray(Stream s)
    {
        byte[] rawLength = new byte[sizeof(int)];
        if (s.Read(rawLength, 0, rawLength.Length) != rawLength.Length)
        {
            throw new InvalidOperationException("流不包含正确格式的字节数组");
        }

        byte[] buffer = new byte[BitConverter.ToInt32(rawLength, 0)];
        if (s.Read(buffer, 0, buffer.Length) != buffer.Length)
        {
            throw new InvalidOperationException("未正确读取字节数组");
        }

        return buffer;
    }
}</code>

2. 使用 Cryptography API

C# 中的 Cryptography API 提供了各種用於安全加密操作的類。以下是如何使用此 API 加密和解密字符串的示例:

<code class="language-csharp">using System.Security.Cryptography;

public static class Crypto
{
    public static string Encrypt(string plainText, string sharedSecret)
    {
        // 创建对称密钥
        SymmetricAlgorithm algorithm = SymmetricAlgorithm.Create("AES");
        byte[] key = DeriveKey(sharedSecret, algorithm.KeySize);

        // 创建加密器
        ICryptoTransform encryptor = algorithm.CreateEncryptor(key, algorithm.IV);

        // 加密数据
        byte[] cipherText = encryptor.TransformFinalBlock(Encoding.UTF8.GetBytes(plainText), 0, plainText.Length);

        // 将加密的字节作为 base64 字符串返回
        return Convert.ToBase64String(cipherText);
    }

    public static string Decrypt(string cipherText, string sharedSecret)
    {
        // 创建对称密钥
        SymmetricAlgorithm algorithm = SymmetricAlgorithm.Create("AES");
        byte[] key = DeriveKey(sharedSecret, algorithm.KeySize);

        // 创建解密器
        ICryptoTransform decryptor = algorithm.CreateDecryptor(key, algorithm.IV);

        // 解密数据
        byte[] plainText = decryptor.TransformFinalBlock(Convert.FromBase64String(cipherText), 0, cipherText.Length);

        // 将解密的文本作为字符串返回
        return Encoding.UTF8.GetString(plainText);
    }

    // 从共享密钥派生密钥的辅助方法
    private static byte[] DeriveKey(string sharedSecret, int keySize)
    {
        // 使用基于密码的密钥派生函数 (PBKDF2)
        Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(sharedSecret, salt, 10000, HashAlgorithmName.SHA256);
        return pbkdf2.GetBytes(keySize / 8);
    }
}</code>

這兩種方法都為保護 C# 中的敏感數據提供了強大的加密和解密機制。 RijndaelManaged 類是一種成熟且廣泛使用的算法,而 Cryptography API 提供了額外的功能和靈活性。 請注意,代碼中省略了salt的定義,實際使用時需要定義一個安全的鹽值。 此外,對於生產環境,建議使用更強大的密鑰管理和更安全的密鑰派生方法。

以上是如何使用RijndaelManed和密碼學API在C#中加密和解密字符串?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn