Smart.Security
6.0.0
dotnet add package Smart.Security --version 6.0.0
NuGet\Install-Package Smart.Security -Version 6.0.0
<PackageReference Include="Smart.Security" Version="6.0.0" />
<PackageVersion Include="Smart.Security" Version="6.0.0" />
<PackageReference Include="Smart.Security" />
paket add Smart.Security --version 6.0.0
#r "nuget: Smart.Security, 6.0.0"
#:package Smart.Security@6.0.0
#addin nuget:?package=Smart.Security&version=6.0.0
#tool nuget:?package=Smart.Security&version=6.0.0
Smart.Security
<a name="english"></a>
English
Smart.Security is a .NET security helper library built on .NET cryptography APIs and BouncyCastle. It provides AES, RSA, SM2, SM3, SM4, hash, HMAC, password salt/hash, file hash, and secure random helpers. It supports .NET 8, 9, and 10.
Installation
dotnet add package Smart.Security
Examples
AES
using Smart.Security;
var key = SmartAESCipher.GenerateKey();
string cipherText = SmartAESCipher.Encrypt("Hello World", key.Key, key.IV);
string plainText = SmartAESCipher.Decrypt(cipherText, key.Key, key.IV);
RSA
using Smart.Security;
var keyPair = SmartRSACipher.GenerateRSAKeyPair(2048);
byte[] data = Encoding.UTF8.GetBytes("Secret Message");
byte[] cipherBytes = SmartRSACipher.Encrypt(keyPair.Public, data);
byte[] plainBytes = SmartRSACipher.Decrypt(keyPair.Private, cipherBytes);
byte[] signature = SmartRSACipher.Sign(keyPair.Private, data);
bool valid = SmartRSACipher.VerifySign(keyPair.Public, data, signature);
SM2 / SM3 / SM4
byte[] sm3 = SmartSM3Hash.SM3Hash(Encoding.UTF8.GetBytes("Data to hash"));
var sm4Key = SmartSM4Cipher.GenerateKey();
string sm4Cipher = SmartSM4Cipher.Encrypt("SM4 message", sm4Key.Base64Key, sm4Key.Base64IV);
string sm4Plain = SmartSM4Cipher.Decrypt(sm4Cipher, sm4Key.Base64Key, sm4Key.Base64IV);
byte[] sm2Cipher = SmartSM2Cipher.Encrypt(publicKeyBytes, plainBytes);
byte[] sm2Plain = SmartSM2Cipher.Decrypt(privateKeyBytes, sm2Cipher);
byte[] sm2Signature = SmartSM2Cipher.Sign(privateKeyBytes, plainBytes);
bool sm2Valid = SmartSM2Cipher.VerifySign(publicKeyBytes, plainBytes, sm2Signature);
Hash And HMAC
byte[] data = Encoding.UTF8.GetBytes("Data to hash");
byte[] sha256 = SmartHash.SHA256Hash(data);
byte[] sha512 = SmartHash.SHA512Hash(data);
byte[] hmac = SmartHash.HmacSHA256(data, "please-change-this-hmac-key-32bytes");
The string key overloads treat the key as UTF-8 text and require at least 16 bytes; if your key is Base64 text, use SmartHash.HmacSHA256FromBase64Key(data, base64Key) instead.
The string overloads default to UTF-8. When you need to match a system that encodes text differently (GBK/ANSI/Unicode/...), pass the encoding explicitly — every hash and HMAC method has a matching overload:
// GB2312/GBK and other code pages need the provider registered once at startup
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
byte[] utf8Md5 = SmartHash.MD5Hash("你好"); // 7eca689f0d3389d9dea66ae112e5cfd7
byte[] gbkMd5 = SmartHash.MD5Hash("你好", Encoding.GetEncoding("gb2312")); // b94ae3c6d892b29cf48d9bea819b27b9
byte[] gbkHmac = SmartHash.HmacSHA256("你好", "please-change-this-hmac-key-32bytes", Encoding.GetEncoding("gb2312"));
Plain ASCII text produces the same bytes in UTF-8, GBK and ASCII, so an encoding mismatch only shows up on non-ASCII input. The hash is always computed over bytes, never over characters — confirm the encoding before blaming the algorithm.
File Hash
byte[] md5 = SmartFileHash.MD5Hash(filePath);
byte[] sha256 = await SmartFileHash.SHA256HashAsync(filePath);
Password Salt And Hash
SmartPassword generates a Base64 salt and stores a PBKDF2-HMAC-SHA256 hash (600,000 iterations by default) in a versioned format: pbkdf2-sha256$iterations$base64hash. Hashes created by 5.x (single SHA256) are still verified, and NeedsRehash tells you when to upgrade one.
string salt = SmartPassword.GenerateSalt();
string hash = SmartPassword.HashPassword("user_password", salt);
bool valid = SmartPassword.VerifyPassword("user_password", salt, hash);
Secure Random
string base64Key = SmartRandom.GenerateKey(256);
byte[] bytes = SmartRandom.RandomArray(32);
string text = SmartRandom.RandomString(16);
string digits = SmartRandom.RandomNumber(6);
long number = SmartRandom.RandomLong();
Breaking Changes In 6.0
SmartAESCipher.Encrypt/Decryptno longer falls back to an all-zero IV: CBC/CFB/CTS throw whenivisnull. Always pass a fresh random IV.SmartRSACipher.Encrypt/Decryptdefault padding changed from raw RSA to OAEP-SHA256, and an unknown padding string now throws instead of silently using raw RSA.- HMAC
string keyoverloads interpret the key as UTF-8 (5.x treated it as Base64). Use theHmacXxxFromBase64Keyoverloads for Base64 keys, and keys must be at least 16 bytes. SmartPassword.HashPasswordreturnspbkdf2-sha256$...instead of a bare Base64 SHA256 digest. Verification of old hashes still works.SmartFileHashhashes SM3 in a stream, so multi-GB files no longer load into memory.SmartSM2Ciphervalidates curve names, key lengths and pubkey encodings, and accepts 64-byte keys (no0x04prefix).
Security Notes
- Prefer SHA256/384/512 over MD5/SHA1 for new scenarios.
- Use RSA keys of at least 2048 bits.
- Keep encryption keys and salts in secure storage.
- Use unique IV values for each encryption operation, and never reuse an IV in CBC mode.
- AES/SM4 in CBC or ECB mode provide no integrity protection; use AEAD or Encrypt-then-MAC when authenticity matters, and never return raw decryption errors to clients.
- Use PBKDF2/Argon2 for password digests instead of a single SHA256 round.
<a name="chinese"></a>
中文
Smart.Security 是基于 .NET 密码学 API 和 BouncyCastle 的安全工具库,提供 AES、RSA、SM2、SM3、SM4、哈希、HMAC、密码盐值/哈希、文件哈希和安全随机数等能力,兼容 .NET 8/9/10。
安装
dotnet add package Smart.Security
示例
AES
using Smart.Security;
var key = SmartAESCipher.GenerateKey();
string cipherText = SmartAESCipher.Encrypt("Hello World", key.Key, key.IV);
string plainText = SmartAESCipher.Decrypt(cipherText, key.Key, key.IV);
RSA
using Smart.Security;
var keyPair = SmartRSACipher.GenerateRSAKeyPair(2048);
byte[] data = Encoding.UTF8.GetBytes("Secret Message");
byte[] cipherBytes = SmartRSACipher.Encrypt(keyPair.Public, data);
byte[] plainBytes = SmartRSACipher.Decrypt(keyPair.Private, cipherBytes);
byte[] signature = SmartRSACipher.Sign(keyPair.Private, data);
bool valid = SmartRSACipher.VerifySign(keyPair.Public, data, signature);
SM2 / SM3 / SM4
byte[] sm3 = SmartSM3Hash.SM3Hash(Encoding.UTF8.GetBytes("待哈希数据"));
var sm4Key = SmartSM4Cipher.GenerateKey();
string sm4Cipher = SmartSM4Cipher.Encrypt("SM4 消息", sm4Key.Base64Key, sm4Key.Base64IV);
string sm4Plain = SmartSM4Cipher.Decrypt(sm4Cipher, sm4Key.Base64Key, sm4Key.Base64IV);
byte[] sm2Cipher = SmartSM2Cipher.Encrypt(publicKeyBytes, plainBytes);
byte[] sm2Plain = SmartSM2Cipher.Decrypt(privateKeyBytes, sm2Cipher);
byte[] sm2Signature = SmartSM2Cipher.Sign(privateKeyBytes, plainBytes);
bool sm2Valid = SmartSM2Cipher.VerifySign(publicKeyBytes, plainBytes, sm2Signature);
哈希与 HMAC
byte[] data = Encoding.UTF8.GetBytes("待哈希数据");
byte[] sha256 = SmartHash.SHA256Hash(data);
byte[] sha512 = SmartHash.SHA512Hash(data);
byte[] hmac = SmartHash.HmacSHA256(data, "please-change-this-hmac-key-32bytes");
string key 重载把密钥按 UTF-8 文本处理,长度不得小于 16 字节;密钥本身是 Base64 文本时请改用 SmartHash.HmacSHA256FromBase64Key(data, base64Key)。
字符串重载默认按 UTF-8 编码。需要与按 GBK/ANSI/Unicode 等编码实现的外部系统比对结果时,显式传入编码即可——六个哈希算法与六个 HMAC 方法都有对应的重载:
// GB2312/GBK 等代码页需在启动时注册一次提供程序
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
byte[] utf8Md5 = SmartHash.MD5Hash("你好"); // 7eca689f0d3389d9dea66ae112e5cfd7
byte[] gbkMd5 = SmartHash.MD5Hash("你好", Encoding.GetEncoding("gb2312")); // b94ae3c6d892b29cf48d9bea819b27b9
byte[] gbkHmac = SmartHash.HmacSHA256("你好", "please-change-this-hmac-key-32bytes", Encoding.GetEncoding("gb2312"));
纯 ASCII 文本在 UTF-8/GBK/ASCII 下字节完全相同,所以编码不一致只在非 ASCII 输入上暴露。哈希永远作用在字节序列上而不是字符上——比对不一致时先确认编码,再怀疑算法。
文件哈希
byte[] md5 = SmartFileHash.MD5Hash(filePath);
byte[] sha256 = await SmartFileHash.SHA256HashAsync(filePath);
密码盐值与哈希
SmartPassword 会生成 Base64 盐值,并保存 PBKDF2-HMAC-SHA256 哈希(默认 600,000 次迭代),格式为 pbkdf2-sha256$迭代次数$Base64哈希。5.x 生成的旧哈希仍可校验,可用 NeedsRehash 判断何时升级。
string salt = SmartPassword.GenerateSalt();
string hash = SmartPassword.HashPassword("user_password", salt);
bool valid = SmartPassword.VerifyPassword("user_password", salt, hash);
安全随机数
string base64Key = SmartRandom.GenerateKey(256);
byte[] bytes = SmartRandom.RandomArray(32);
string text = SmartRandom.RandomString(16);
string digits = SmartRandom.RandomNumber(6);
long number = SmartRandom.RandomLong();
6.0 破坏性变更
SmartAESCipher.Encrypt/Decrypt不再回退到全零 IV:CBC/CFB/CTS 模式下iv为null直接抛异常,请始终传入随机 IV。SmartRSACipher.Encrypt/Decrypt默认填充由裸 RSA 改为 OAEP-SHA256,未知填充字符串会抛异常而不是静默降级为裸 RSA。- HMAC 的
string key重载按 UTF-8 解释密钥(5.x 按 Base64),Base64 密钥请用HmacXxxFromBase64Key重载,且密钥长度不得小于 16 字节。 SmartPassword.HashPassword返回pbkdf2-sha256$...而不是裸 Base64 SHA256 摘要,旧哈希仍可校验。SmartFileHash的 SM3 改为流式计算,超大文件不再整体载入内存。SmartSM2Cipher增加了曲线名、密钥长度与公钥编码校验,并支持不带0x04前缀的 64 字节公钥。
安全建议
- 新场景优先使用 SHA256/384/512,避免继续使用 MD5/SHA1。
- RSA 密钥长度建议不低于 2048 位。
- 加密密钥和盐值应存储在安全位置。
- 每次加密操作应使用唯一 IV,且 CBC 模式下不要复用 IV。
- AES/SM4 的 CBC、ECB 模式不含完整性保护,需要认证时请改用 AEAD 或 Encrypt-then-MAC,并避免把解密异常细节返回给客户端。
- 口令摘要推荐 PBKDF2/Argon2,不要使用单轮 SHA256。
Developed by zenglei
| 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. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- BouncyCastle.Cryptography (>= 2.6.2)
-
net8.0
- BouncyCastle.Cryptography (>= 2.6.2)
-
net9.0
- BouncyCastle.Cryptography (>= 2.6.2)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Smart.Security:
| Package | Downloads |
|---|---|
|
BaseLibrary.ClassLibraryStand
Package Description |
|
|
RL.System.Core
山东瑞隆网络技术有限公司 -API |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 6.0.0 | 85 | 11/4/2026 |
| 5.0.0-beta.1 | 95 | 6/17/2026 |
| 4.1.6 | 1,054 | 5/16/2026 |
| 4.1.5 | 270 | 2/11/2026 |
| 4.1.4 | 145 | 2/8/2026 |
| 4.1.3 | 255 | 12/30/2025 |
| 4.1.2 | 298 | 10/15/2025 |
| 4.1.1 | 263 | 7/13/2025 |
| 4.1.0 | 245 | 4/5/2025 |
| 4.0.1 | 331 | 3/23/2025 |
| 4.0.0 | 301 | 3/20/2025 |
| 3.0.2 | 242 | 2/26/2025 |
| 3.0.1 | 265 | 2/15/2025 |
| 3.0.0 | 230 | 2/15/2025 |
| 2.0.2 | 273 | 2/9/2025 |
| 2.0.1 | 244 | 12/7/2024 |
| 1.1.1 | 238 | 12/7/2024 |
| 1.1.0.2 | 267 | 11/11/2024 |