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
<PackageReference Include="Yoko.Tool.Security" Version="1.1.4" />
paket add Yoko.Tool.Security --version 1.1.4
#r "nuget: Yoko.Tool.Security, 1.1.4"
// 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
(防止重放攻击)。 - 请求参数(如
path
、method
)。 - 固定的 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×tamp=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×tamp=1672531199000";
string signature = TokenHelper.GenerateHmacSha512(secretKey, stringToSign);
Console.WriteLine($"HMAC-SHA512 Signature: {signature}");
3. SHA-256 签名
string stringToSign = "data=example×tamp=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×tamp=1672531199000";
string rsaSignature = TokenHelper.GenerateRsaSha256(privateKey, stringToSign);
Console.WriteLine($"RSA-SHA256 Signature: {rsaSignature}");
常见问题
ArgumentException
错误:- 检查传入的参数是否为 null 或空字符串。
- 非对称加密格式错误:
- 确保私钥格式正确,采用标准 PEM 格式。
- 兼容性问题:
- 确保使用 .NET 8 或更高版本,以支持
RSA.ImportFromPem
和静态HashData
方法。
- 确保使用 .NET 8 或更高版本,以支持
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 | Versions 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. |
-
net8.0
- BouncyCastle.Cryptography (>= 2.5.0)
-
net9.0
- BouncyCastle.Cryptography (>= 2.5.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.