Yoko.Tool.Security 1.1.4

dotnet add package Yoko.Tool.Security --version 1.1.4                
NuGet\Install-Package Yoko.Tool.Security -Version 1.1.4                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Yoko.Tool.Security" Version="1.1.4" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Yoko.Tool.Security --version 1.1.4                
#r "nuget: Yoko.Tool.Security, 1.1.4"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Yoko.Tool.Security as a Cake Addin
#addin nuget:?package=Yoko.Tool.Security&version=1.1.4

// Install Yoko.Tool.Security as a Cake Tool
#tool nuget:?package=Yoko.Tool.Security&version=1.1.4                

1、常用加密算法

常用的加密算法的封装,降低加密解密的使用复杂度

  • 目前支持:AES,DES,RC4,RSA,SM2,SM4,MD5

  • 支持 RSA XML 结构的 SecurityKey 和 Base64 格式的互转

  • 本库不是去实现加密算法,而是基于.Net 提供的接口封装,为了方便使用

  • 若是遇到了解密乱码,就在主项目中添加 System.Text.Encoding.CodePages 库,然后注册

    var builder = WebApplication.CreateBuilder(args);
    System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
    

使用示例

AES
// 原始文本数据
string originalText = "Hello, AES Encryption!";
Console.WriteLine("原始数据: " + originalText);

// 将文本数据转换为字节数组
byte[] content = Encoding.UTF8.GetBytes(originalText);

// 设置密码
string password = "mySecretPassword";

// 选择AES加密模式
AesKeyModel keyModel = AesKeyModel.AES256;

// 加密数据
byte[] encryptedData = AesCrypt.Encrypt(content, password, keyModel);
Console.WriteLine("加密后的数据 (Base64): " + Convert.ToBase64String(encryptedData));

// 解密数据
byte[] decryptedData = AesCrypt.Decrypt(encryptedData, password, keyModel);
string decryptedText = Encoding.UTF8.GetString(decryptedData);
Console.WriteLine("解密后的数据: " + decryptedText);
DES
string originalText = "Hello, DES Encryption with custom salt!";
Console.WriteLine("原始数据: " + originalText);

byte[] content = Encoding.UTF8.GetBytes(originalText);
string password = "securePassword123";
string customSalt = "myCustomSaltValue";

// DES 加密和解密示例,使用自定义盐值
byte[] encryptedData = DesCrypt.Encrypt(content, password, customSalt);
Console.WriteLine("加密后的数据 (Base64): " + Convert.ToBase64String(encryptedData));

byte[] decryptedData = DesCrypt.Decrypt(encryptedData, password, customSalt);
string decryptedText = Encoding.UTF8.GetString(decryptedData);
Console.WriteLine("解密后的数据: " + decryptedText);
RC4
/// <summary>
/// RC4
/// </summary>
public void Rc4()
{
    const string data = "Microsoft";
    var key = "123456"u8.ToArray();
    var byte_data = Encoding.UTF8.GetBytes(data);
    var secret = Rc4Crypt.Encrypt(byte_data, key);
    var base64 = secret.ToBase64();
    // TZEdFUtAevoL
    var data_result = Rc4Crypt.Decrypt(secret, key);
    var result = Encoding.UTF8.GetString(data_result);
    // result == data
}
RSA
// 1. 初始化密钥对
Console.WriteLine("生成密钥对...");
var rsaKey = RsaCrypt.GenerateKey(2048);

// 提取 Base64 格式的公钥和私钥
string publicKey = rsaKey.PublicKey;
string privateKey = rsaKey.PrivateKey;

Console.WriteLine("\nBase64 格式密钥:");
Console.WriteLine($"公钥:\n{publicKey}");
Console.WriteLine($"私钥:\n{privateKey}");

// 2. 短数据加密与解密
string shortMessage = "Hello, 这是一条短数据!";
Console.WriteLine("\n原始短消息:");
Console.WriteLine(shortMessage);

byte[] shortMessageBytes = Encoding.UTF8.GetBytes(shortMessage);

// 短数据加密
byte[] shortEncryptedBytes = RsaCrypt.EncryptLong(publicKey, shortMessageBytes);
Console.WriteLine("\n短消息加密后 (Base64):");
Console.WriteLine(Convert.ToBase64String(shortEncryptedBytes));

// 短数据解密
byte[] shortDecryptedBytes = RsaCrypt.DecryptLong(privateKey, shortEncryptedBytes);
string shortDecryptedMessage = Encoding.UTF8.GetString(shortDecryptedBytes);
Console.WriteLine("\n短消息解密后:");
Console.WriteLine(shortDecryptedMessage);

// 3. 超长数据加密与解密
string longMessage = string.Join("", Enumerable.Repeat("床前明月光,疑似地上霜。", 50));
Console.WriteLine("\n原始超长消息:");
Console.WriteLine(longMessage);

byte[] longMessageBytes = Encoding.UTF8.GetBytes(longMessage);

// 超长数据加密
Console.WriteLine("\n加密超长消息中...");
byte[] longEncryptedBytes = RsaCrypt.EncryptLong(publicKey, longMessageBytes);
Console.WriteLine("超长消息加密后 (Base64):");
Console.WriteLine(Convert.ToBase64String(longEncryptedBytes));

// 超长数据解密
Console.WriteLine("\n解密超长消息中...");
byte[] longDecryptedBytes = RsaCrypt.DecryptLong(privateKey, longEncryptedBytes);
string longDecryptedMessage = Encoding.UTF8.GetString(longDecryptedBytes);
Console.WriteLine("超长消息解密后:");
Console.WriteLine(longDecryptedMessage);

// 验证解密结果是否正确
Console.WriteLine("\n超长消息解密验证结果:");
Console.WriteLine(longDecryptedMessage == longMessage ? "解密成功" : "解密失败");

// 4. 私钥签名与公钥验证
Console.WriteLine("\n签名和验证操作:");

// 数据摘要
byte[] hashData = SHA256.HashData(shortMessageBytes);

// 签名
Console.WriteLine("\n生成签名...");
byte[] signature = RsaCrypt.Signature(privateKey, hashData);
Console.WriteLine("签名 (Base64):");
Console.WriteLine(Convert.ToBase64String(signature));

// 验证签名
Console.WriteLine("\n验证签名...");
bool isVerified = RsaCrypt.Verification(publicKey, hashData, signature);
Console.WriteLine($"签名验证结果: {(isVerified ? "成功" : "失败")}");
SM2
// 1. 生成密钥对
Sm2Crypt.GenerateKey(out byte[] publicKey, out byte[] privateKey);
Console.WriteLine("生成的公钥: " + Convert.ToBase64String(publicKey));
Console.WriteLine("生成的私钥: " + Convert.ToBase64String(privateKey));

// 设置待加密和签名的数据
string message = "Hello, SM2!";
byte[] data = Encoding.UTF8.GetBytes(message);

// 2. 使用公钥进行加密
byte[] encryptedData = Sm2Crypt.Encrypt(publicKey, data);
Console.WriteLine("加密后的数据: " + Convert.ToBase64String(encryptedData));

// 3. 使用私钥进行解密
byte[] decryptedData = Sm2Crypt.Decrypt(privateKey, encryptedData);
Console.WriteLine("解密后的数据: " + Encoding.UTF8.GetString(decryptedData));

// 4. 使用私钥签名
byte[] signature = Sm2Crypt.Signature(privateKey, data);
Console.WriteLine("签名: " + Convert.ToBase64String(signature));

// 5. 使用公钥验签
bool isVerified = Sm2Crypt.Verify(publicKey, data, signature);
Console.WriteLine("验签结果: " + (isVerified ? "成功" : "失败"));
SM4
/// <summary>
/// SM4ECB模式加密到Base64格式
/// </summary>
public void Sm4EncryptECBToBase64()
{
    const string data = "Microsoft";
    // 将原文解析到二进制数组格式
    var byte_data = Encoding.UTF8.GetBytes(data);
    // 进制格式密钥加密数据
    var result = Sm4Crypt.EncryptECB("701d1cc0cfbe7ee11824df718855c0c6", true, byte_data);
    // 获取Base64格式的字符串结果
    var base64 = result.ToBase64();
    // ThRruxZZm1GrHE5KkP4UmQ==
}

/// <summary>
/// SM4ECB模式解密Base64格式到字符串
/// </summary>
public void Sm4DecryptECBTest()
{
    // Base64格式的
    const string data = "ThRruxZZm1GrHE5KkP4UmQ==";
    // 将Base64格式字符串转为 byte[]
    var byte_data = Convert.FromBase64String(data);
    // 通过16进制格式密钥解密数据
    var result = Sm4Crypt.DecryptECB("701d1cc0cfbe7ee11824df718855c0c6", true, byte_data);
    // 解析结果获取字符串
    var str = Encoding.UTF8.GetString(result);
    // Microsoft
}

/// <summary>
/// SM4ECB模式加密到16进制字符串
/// </summary>
public void Sm4EncryptECBToHex16()
{
    const string data = "Microsoft";
    // 将原文解析到二进制数组格式
    var byte_data = Encoding.UTF8.GetBytes(data);
    // 使用16位长度的密钥加密
    var result = Sm4Crypt.EncryptECB("1cc0cfbe7ee11824", false, byte_data);
    // 将结果转为16进制字符串
    var hex = result.ToHexString();
    // D265DF0510C05FE836D3113B3ACEC714
}

/// <summary>
/// SM4ECB模式解密16进制字符串格式密文
/// </summary>
public void Sm4DecryptECBTest2()
{
    const string data = "D265DF0510C05FE836D3113B3ACEC714";
    var byte_data = data.FromHex();
    var result = Sm4Crypt.DecryptECB("1cc0cfbe7ee11824", false, byte_data);
    // 解析结果获取字符串
    var str = Encoding.UTF8.GetString(result);
    // Microsoft
}

/// <summary>
/// SM4CBC模式加密到Base64格式
/// </summary>
public void Sm4EncryptCBCTest()
{
    const string data = "Microsoft";
    var byte_data = Encoding.UTF8.GetBytes(data);
    var result = Sm4Crypt.EncryptCBC("701d1cc0cfbe7ee11824df718855c0c6", true, "701d1cc0cfbe7ee11824df718855c0c5", byte_data);
    var base64 = result.ToBase64();
    // Q2iUaMuSHjLvq6GhUQnGTg==
}

/// <summary>
/// SM4CBC模式从Base64解密
/// </summary>
public void Sm4DecryptCBCTest()
{
    const string data = "Q2iUaMuSHjLvq6GhUQnGTg==";
    var byte_data = Convert.FromBase64String(data);
    var result = Sm4Crypt.DecryptCBC("701d1cc0cfbe7ee11824df718855c0c6", true, "701d1cc0cfbe7ee11824df718855c0c5", byte_data);
    var str = Encoding.UTF8.GetString(result);
    // Microsoft
}

/// <summary>
/// SM4CBC模式加密到16进制字符串
/// </summary>
public void Sm4EncryptCBCTest2()
{
    const string data = "Microsoft";
    var byte_data = Encoding.UTF8.GetBytes(data);
    var result = Sm4Crypt.EncryptCBC("1cc0cfbe7ee11824", false, "1cc0cfbe7ee12824", byte_data);
    var hex = result.ToHexString();
    // 1BD7A32E49B60B17698AAC9D1E4FEE4A
}

/// <summary>
/// SM4CBC模式从Hex16解密到字符串
/// </summary>
public void Sm4DecryptCBCTest2()
{
    const string data = "1BD7A32E49B60B17698AAC9D1E4FEE4A";
    var byte_data = data.FromHex();
    var result = Sm4Crypt.DecryptCBC("1cc0cfbe7ee11824", false, "1cc0cfbe7ee12824", byte_data);
    var str = Encoding.UTF8.GetString(result);
    // Microsoft
}
MD5
// 输入字符串
string input = "Hello, MD5 Encryption!";
Console.WriteLine("原始数据: " + input);

// 获取32位长度的MD5大写字符串
string md5Hash32 = input.To32MD5();
Console.WriteLine("32位MD5哈希: " + md5Hash32);

// 获取16位长度的MD5大写字符串
string md5Hash16 = input.To16MD5();
Console.WriteLine("16位MD5哈希: " + md5Hash16);

2、TokenHelper

TokenHelper 提供了一套通用方法,用于生成基于不同加密算法的签名字符串,支持多种国际通用的加密算法。 常见的场景包括 API 调用认证、数据完整性校验、以及安全通信。

方法概览

1. GenerateHmacSha256

使用 HMAC-SHA256 算法生成签名。

参数:

  • secretKey (string): 秘钥,用于生成签名的安全密钥。
  • stringToSign (string): 需要签名的字符串,一般由特定的业务逻辑生成。

返回值: 返回 Base64 编码的签名字符串。

适用场景: 常用于 API 调用中带有时间戳的签名,保障消息的完整性和安全性。


2. GenerateHmacSha512

使用 HMAC-SHA512 算法生成签名。

参数:

  • secretKey (string): 秘钥,用于生成签名的安全密钥。
  • stringToSign (string): 需要签名的字符串。

返回值: 返回 Base64 编码的签名字符串。

适用场景: 适用于需要更高安全性和更长签名长度的场景,如文件传输校验。


3. GenerateSha256

使用 SHA-256 算法生成签名。

参数:

  • stringToSign (string): 需要签名的字符串。

返回值: 返回 Base64 编码的签名字符串。

适用场景: 用于生成固定签名值的场景,无需额外秘钥,如文件哈希校验。


4. GenerateRsaSha256

使用 RSA-SHA256 算法生成签名。

参数:

  • privateKey (string): RSA 私钥(PEM 格式)。
  • stringToSign (string): 需要签名的字符串。

返回值: 返回 Base64 编码的签名字符串。

适用场景: 适用于非对称加密的签名机制,如 HTTPS 证书签名、JWT 非对称签名。


方法使用注意事项

1. 参数解释
  • 秘钥 (secretKey) 和私钥 (privateKey)
    • secretKey: 用于对称加密算法(如 HMAC),生成签名时需要同时保密,不可泄露。
    • privateKey: 用于非对称加密算法(如 RSA),仅私钥签名,公钥可用于验证。
  • stringToSign 的构建 签名字符串的构建需要满足固定顺序或格式,一般包括:
    • 时间戳 timestamp(防止重放攻击)。
    • 请求参数(如 pathmethod)。
    • 固定的 appId 或 API 密钥。
2. 安全性
  • 加密强度
    • HMAC-SHA512 和 RSA-SHA256 强度更高,但需要根据业务需求权衡性能开销。
    • HMAC-SHA256 是对称加密中最常用的方案。
  • 密钥管理: 密钥或私钥需妥善存储,建议使用专用密钥管理服务(如 AWS KMS、Azure Key Vault)。
3. 性能考虑
  • 静态方法: 本工具方法为静态实现,避免实例化,性能更优。
  • 加密算法选择: 根据签名长度、计算速度选择合适算法。

使用示例

1. HMAC-SHA256 签名
string secretKey = "YourSecretKey";
string stringToSign = "appId=123456&timestamp=1672531199000&path=/api/v1/upload";

string signature = TokenHelper.GenerateToken(secretKey, stringToSign);
Console.WriteLine($"HMAC-SHA256 Signature: {signature}");

2. HMAC-SHA512 签名
string secretKey = "YourSecretKey";
string stringToSign = "data=example&timestamp=1672531199000";

string signature = TokenHelper.GenerateHmacSha512(secretKey, stringToSign);
Console.WriteLine($"HMAC-SHA512 Signature: {signature}");

3. SHA-256 签名
string stringToSign = "data=example&timestamp=1672531199000";

string hash = TokenHelper.GenerateSha256(stringToSign);
Console.WriteLine($"SHA-256 Hash: {hash}");

4. RSA-SHA256 签名
string privateKey = @"
-----BEGIN PRIVATE KEY-----
YourPrivateKeyHere
-----END PRIVATE KEY-----
";
string stringToSign = "data=example&timestamp=1672531199000";

string rsaSignature = TokenHelper.GenerateRsaSha256(privateKey, stringToSign);
Console.WriteLine($"RSA-SHA256 Signature: {rsaSignature}");

常见问题

  1. ArgumentException 错误:
    • 检查传入的参数是否为 null 或空字符串。
  2. 非对称加密格式错误:
    • 确保私钥格式正确,采用标准 PEM 格式。
  3. 兼容性问题:
    • 确保使用 .NET 8 或更高版本,以支持 RSA.ImportFromPem 和静态 HashData 方法。

3、更新日志

1.1.4

【新增】RSA对于超长类型的加解密,新增EncryptLong、DecryptLong,原Encrypt、Decrypt超长类型的加解密的重载方法保留

1.1.3

【更新】更新依赖、更新RSA超长数据加解密

1.1.2

【更新】优化操作步骤

1.1.1

【更新】部分加密方法性能优化 【移除】移除对Net6的兼容性

1.1.0

【新增】TokenHelper 常用 token生成方法

1.0.1

【新增】Net6的支持

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.4 85 12/3/2024
1.1.3 84 12/3/2024