当前位置: 首页 > article >正文

C#中的加密和解密类设计

下面是一个基于 ProtectedData 类和 DataProtectionScope 的静态类 Cypher 的设计,用于加密和解密数据。该类封装了加密和解密的逻辑,并提供了简单易用的接口。

设计目标
封装加密和解密逻辑:

提供静态方法 Encrypt 和 Decrypt,分别用于加密和解密数据。

支持字符串和字节数组的加密和解密。

支持自定义熵:

允许用户提供可选的熵(optionalEntropy)以增加安全性。

异常处理:

捕获并处理加密和解密过程中可能抛出的异常。

灵活性:

支持 DataProtectionScope.CurrentUser 和 DataProtectionScope.LocalMachine。

实现代码

using System;
using System.Security.Cryptography;
using System.Text;

public static class Cypher
{
    /// <summary>
    /// 加密字符串。
    /// </summary>
    /// <param name="data">要加密的字符串。</param>
    /// <param name="scope">数据保护范围(默认当前用户)。</param>
    /// <param name="optionalEntropy">可选的熵(增加安全性)。</param>
    /// <returns>加密后的 Base64 字符串。</returns>
    public static string Encrypt(string data, DataProtectionScope scope = DataProtectionScope.CurrentUser, byte[] optionalEntropy = null)
    {
        if (string.IsNullOrEmpty(data))
            throw new ArgumentNullException(nameof(data));

        try
        {
            byte[] dataBytes = Encoding.UTF8.GetBytes(data);
            byte[] encryptedBytes = ProtectedData.Protect(dataBytes, optionalEntropy, scope);
            return Convert.ToBase64String(encryptedBytes);
        }
        catch (Exception ex)
        {
            throw new CryptographicException("加密失败。", ex);
        }
    }

    /// <summary>
    /// 解密字符串。
    /// </summary>
    /// <param name="encryptedData">加密后的 Base64 字符串。</param>
    /// <param name="scope">数据保护范围(默认当前用户)。</param>
    /// <param name="optionalEntropy">可选的熵(必须与加密时一致)。</param>
    /// <returns>解密后的原始字符串。</returns>
    public static string Decrypt(string encryptedData, DataProtectionScope scope = DataProtectionScope.CurrentUser, byte[] optionalEntropy = null)
    {
        if (string.IsNullOrEmpty(encryptedData))
            throw new ArgumentNullException(nameof(encryptedData));

        try
        {
            byte[] encryptedBytes = Convert.FromBase64String(encryptedData);
            byte[] decryptedBytes = ProtectedData.Unprotect(encryptedBytes, optionalEntropy, scope);
            return Encoding.UTF8.GetString(decryptedBytes);
        }
        catch (Exception ex)
        {
            throw new CryptographicException("解密失败。", ex);
        }
    }

    /// <summary>
    /// 加密字节数组。
    /// </summary>
    /// <param name="data">要加密的字节数组。</param>
    /// <param name="scope">数据保护范围(默认当前用户)。</param>
    /// <param name="optionalEntropy">可选的熵(增加安全性)。</param>
    /// <returns>加密后的字节数组。</returns>
    public static byte[] Encrypt(byte[] data, DataProtectionScope scope = DataProtectionScope.CurrentUser, byte[] optionalEntropy = null)
    {
        if (data == null || data.Length == 0)
            throw new ArgumentNullException(nameof(data));

        try
        {
            return ProtectedData.Protect(data, optionalEntropy, scope);
        }
        catch (Exception ex)
        {
            throw new CryptographicException("加密失败。", ex);
        }
    }

    /// <summary>
    /// 解密字节数组。
    /// </summary>
    /// <param name="encryptedData">加密后的字节数组。</param>
    /// <param name="scope">数据保护范围(默认当前用户)。</param>
    /// <param name="optionalEntropy">可选的熵(必须与加密时一致)。</param>
    /// <returns>解密后的原始字节数组。</returns>
    public static byte[] Decrypt(byte[] encryptedData, DataProtectionScope scope = DataProtectionScope.CurrentUser, byte[] optionalEntropy = null)
    {
        if (encryptedData == null || encryptedData.Length == 0)
            throw new ArgumentNullException(nameof(encryptedData));

        try
        {
            return ProtectedData.Unprotect(encryptedData, optionalEntropy, scope);
        }
        catch (Exception ex)
        {
            throw new CryptographicException("解密失败。", ex);
        }
    }
}

使用示例
1. 加密和解密字符串

class Program
{
    static void Main()
    {
        try
        {
            string originalText = "这是一个秘密消息!";
            Console.WriteLine("原始数据: " + originalText);

            // 加密
            string encryptedText = Cypher.Encrypt(originalText);
            Console.WriteLine("加密后的数据: " + encryptedText);

            // 解密
            string decryptedText = Cypher.Decrypt(encryptedText);
            Console.WriteLine("解密后的数据: " + decryptedText);
        }
        catch (Exception ex)
        {
            Console.WriteLine("错误: " + ex.Message);
        }
    }
}

2. 使用自定义熵

class Program
{
    static void Main()
    {
        try
        {
            string originalText = "这是一个秘密消息!";
            byte[] entropy = Encoding.UTF8.GetBytes("MySecretEntropy");

            // 加密
            string encryptedText = Cypher.Encrypt(originalText, optionalEntropy: entropy);
            Console.WriteLine("加密后的数据: " + encryptedText);

            // 解密
            string decryptedText = Cypher.Decrypt(encryptedText, optionalEntropy: entropy);
            Console.WriteLine("解密后的数据: " + decryptedText);
        }
        catch (Exception ex)
        {
            Console.WriteLine("错误: " + ex.Message);
        }
    }
}

3. 加密和解密字节数组

class Program
{
    static void Main()
    {
        try
        {
            byte[] originalData = Encoding.UTF8.GetBytes("这是一个秘密消息!");

            // 加密
            byte[] encryptedData = Cypher.Encrypt(originalData);
            Console.WriteLine("加密后的数据: " + Convert.ToBase64String(encryptedData));

            // 解密
            byte[] decryptedData = Cypher.Decrypt(encryptedData);
            Console.WriteLine("解密后的数据: " + Encoding.UTF8.GetString(decryptedData));
        }
        catch (Exception ex)
        {
            Console.WriteLine("错误: " + ex.Message);
        }
    }
}

总结
Cypher 类 封装了加密和解密的逻辑,提供了简单易用的接口。

支持字符串和字节数组的加密和解密。

允许使用自定义熵以增加安全性。

通过异常处理确保代码的健壮性。

这个设计可以满足大多数基于 ProtectedData 的加密和解密需求,同时保持了代码的简洁性和可维护性。


http://www.kler.cn/a/552882.html

相关文章:

  • 网络工程师 (43)IP数据报
  • SCANet代码解读
  • 爬取网站内容转为markdown 和 html(通常模式)
  • kotlin Java 使用ArrayList.add() ,set()前面所有值被 覆盖 的问题
  • 上证50股指期货持仓量查询的方式在哪里?
  • STL之string类的模拟实现
  • Pilz安全继电器介绍(PNOZ X2.8P,Pilz MB0)
  • DeepSeek:情智机器人的“情感引擎”与未来变革者
  • Zookeeper 和 Redis 哪种更好?
  • 一键部署开源DeepSeek并集成到钉钉
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_get_full_name 函数
  • C++核心指导原则: 函数部分
  • C++字符串处理指南:从基础操作到性能优化——基于std::string的全面解析
  • 【QT常用技术讲解】国产Linux桌面系统+window系统通过窗口句柄对窗口进行操作
  • Jtti.cc:CentOS下PyTorch运行出错怎么办
  • Java集合之ArrayList(含源码解析 超详细)
  • 测试。。。
  • 在高流量下保持WordPress网站的稳定和高效运行
  • C++中为什么有了tuple还需要pair?
  • DeepSeek和ChatGPT的全面对比