CSharpCryptoUtils 0.0.3
dotnet add package CSharpCryptoUtils --version 0.0.3
NuGet\Install-Package CSharpCryptoUtils -Version 0.0.3
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="CSharpCryptoUtils" Version="0.0.3" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CSharpCryptoUtils" Version="0.0.3" />
<PackageReference Include="CSharpCryptoUtils" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CSharpCryptoUtils --version 0.0.3
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: CSharpCryptoUtils, 0.0.3"
#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.
#:package CSharpCryptoUtils@0.0.3
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CSharpCryptoUtils&version=0.0.3
#tool nuget:?package=CSharpCryptoUtils&version=0.0.3
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
CSharpCryptoUtils
一个为区块链和金融科技应用提供加密工具的 C# 库,包括加密、哈希和密钥管理功能。
特性
- 🔐 基于 ECDSA P-521 曲线的密钥生成
- ✍️ 数字签名与验证(SHA-512 哈希算法)
- 🔄 密钥导入/导出(支持 JWK 和 Hex 格式)
- 🌐 跨平台兼容(与 Web Crypto API、TypeScript、Flutter 等平台互操作)
- 📦 支持 .NET 7.0, 8.0, 9.0
安装
NuGet Package Manager
dotnet add package CSharpCryptoUtils
或在 Visual Studio 的包管理器控制台中:
Install-Package CSharpCryptoUtils
快速开始
1. 生成密钥对
using CSharpCryptoUtils;
// 生成新的 ECDSA P-521 密钥对
var keyPair = await KeyGenerator.GenerateKeyPairAsync();
Console.WriteLine("密钥对生成成功!");
2. 数字签名
// 对数据进行签名
string testData = "Hello, World!";
string signature = await keyPair.PrivateKey.SignAsync(testData);
Console.WriteLine($"签名: {signature}");
3. 验证签名
// 验证签名
bool isValid = await keyPair.PublicKey.VerifyAsync(signature, testData);
if (isValid)
{
Console.WriteLine("✓ 签名验证成功");
}
else
{
Console.WriteLine("✗ 签名验证失败");
}
详细使用指南
密钥管理
导出私钥(JWK 格式)
// 导出私钥为 JSON Web Key (JWK) 格式
string jwkString = await keyPair.PrivateKey.ExportKeyAsJWKStringAsync();
// JWK 示例:
// {
// "kty": "EC",
// "crv": "P-521",
// "d": "base64url_encoded_private_key",
// "x": "base64url_encoded_x_coordinate",
// "y": "base64url_encoded_y_coordinate",
// "ext": true
// }
Console.WriteLine($"私钥 (JWK): {jwkString}");
// 保存到文件
await File.WriteAllTextAsync("private-key.json", jwkString);
导入私钥(从 JWK)
// 从文件读取
string jwkString = await File.ReadAllTextAsync("private-key.json");
// 导入私钥
var privateKey = await PrivateKey.FromJWKStringAsync(jwkString);
// 使用导入的私钥进行签名
string signature = await privateKey.SignAsync("Test message");
导出公钥(十六进制格式)
// 导出公钥为十六进制字符串
// 格式: X坐标(66字节) + Y坐标(66字节) = 132字节 = 264个十六进制字符
string hexString = await keyPair.PublicKey.ExportKeyAsHexStringAsync();
Console.WriteLine($"公钥长度: {hexString.Length} 个字符"); // 264
Console.WriteLine($"公钥 (Hex): {hexString}");
// 保存到文件
await File.WriteAllTextAsync("public-key.hex", hexString);
导入公钥(从十六进制)
// 从文件读取
string hexString = await File.ReadAllTextAsync("public-key.hex");
// 导入公钥
var publicKey = await PublicKey.FromHexStringAsync(hexString);
// 使用导入的公钥验证签名
bool isValid = await publicKey.VerifyAsync(signature, "Test message");
完整示例
示例 1:密钥生成、签名与验证
using CSharpCryptoUtils;
public class CryptoExample
{
public static async Task Main()
{
// 1. 生成密钥对
var keyPair = await KeyGenerator.GenerateKeyPairAsync();
Console.WriteLine("✓ 密钥对生成成功");
// 2. 导出并保存密钥
var privateKeyJwk = await keyPair.PrivateKey.ExportKeyAsJWKStringAsync();
var publicKeyHex = await keyPair.PublicKey.ExportKeyAsHexStringAsync();
await File.WriteAllTextAsync("private.json", privateKeyJwk);
await File.WriteAllTextAsync("public.hex", publicKeyHex);
Console.WriteLine("✓ 密钥已保存");
// 3. 签名数据
string message = "Important transaction data";
string signature = await keyPair.PrivateKey.SignAsync(message);
Console.WriteLine($"✓ 签名: {signature.Substring(0, 32)}...");
// 4. 验证签名
bool isValid = await keyPair.PublicKey.VerifyAsync(signature, message);
Console.WriteLine($"✓ 签名验证: {(isValid ? "成功" : "失败")}");
// 5. 使用错误的数据验证(应该失败)
bool isInvalid = await keyPair.PublicKey.VerifyAsync(signature, "Wrong data");
Console.WriteLine($"✓ 错误数据验证: {(isInvalid ? "成功" : "失败")} (预期失败)");
}
}
示例 2:密钥持久化与恢复
using CSharpCryptoUtils;
public class KeyPersistenceExample
{
// 保存密钥对
public static async Task SaveKeyPair(KeyPair keyPair, string directory)
{
Directory.CreateDirectory(directory);
var privateKeyJwk = await keyPair.PrivateKey.ExportKeyAsJWKStringAsync();
var publicKeyHex = await keyPair.PublicKey.ExportKeyAsHexStringAsync();
await File.WriteAllTextAsync(Path.Combine(directory, "private.json"), privateKeyJwk);
await File.WriteAllTextAsync(Path.Combine(directory, "public.hex"), publicKeyHex);
}
// 加载密钥对
public static async Task<(PrivateKey, PublicKey)> LoadKeyPair(string directory)
{
var privateKeyJwk = await File.ReadAllTextAsync(Path.Combine(directory, "private.json"));
var publicKeyHex = await File.ReadAllTextAsync(Path.Combine(directory, "public.hex"));
var privateKey = await PrivateKey.FromJWKStringAsync(privateKeyJwk);
var publicKey = await PublicKey.FromHexStringAsync(publicKeyHex);
return (privateKey, publicKey);
}
public static async Task Main()
{
// 生成并保存
var keyPair = await KeyGenerator.GenerateKeyPairAsync();
await SaveKeyPair(keyPair, "./keys");
Console.WriteLine("✓ 密钥已保存到 ./keys 目录");
// 加载并使用
var (privateKey, publicKey) = await LoadKeyPair("./keys");
string message = "Test message";
string signature = await privateKey.SignAsync(message);
bool isValid = await publicKey.VerifyAsync(signature, message);
Console.WriteLine($"✓ 密钥恢复成功,签名验证: {(isValid ? "通过" : "失败")}");
}
}
示例 3:跨平台密钥共享
using CSharpCryptoUtils;
using System.Text.Json;
public class CrossPlatformExample
{
public static async Task Main()
{
// 生成密钥对
var keyPair = await KeyGenerator.GenerateKeyPairAsync();
// 导出为 JWK(可以与 JavaScript/TypeScript 共享)
var privateKeyJwk = await keyPair.PrivateKey.ExportKeyAsJWKStringAsync();
var publicKeyHex = await keyPair.PublicKey.ExportKeyAsHexStringAsync();
Console.WriteLine("=== 私钥 (JWK - 用于 JavaScript/TypeScript) ===");
Console.WriteLine(JsonSerializer.Serialize(
JsonSerializer.Deserialize<object>(privateKeyJwk),
new JsonSerializerOptions { WriteIndented = true }
));
Console.WriteLine("\n=== 公钥 (Hex - 用于各种平台) ===");
Console.WriteLine(publicKeyHex);
// 在 C# 中签名
string message = "Cross-platform message";
string signature = await keyPair.PrivateKey.SignAsync(message);
Console.WriteLine($"\n=== 签名 (Hex) ===");
Console.WriteLine(signature);
// 这个签名可以在其他平台使用相同的公钥进行验证
// 例如在 JavaScript 中:
// const publicKey = await crypto.subtle.importKey("jwk", jwkPublicKey, ...);
// const isValid = await crypto.subtle.verify(..., publicKey, signatureBytes, dataBytes);
}
}
算法规格
加密算法
- 算法: ECDSA (Elliptic Curve Digital Signature Algorithm)
- 曲线: P-521 (secp521r1 / nistP521)
- 哈希: SHA-512
- 签名格式: IEEE P1363 (Raw format - R||S concatenation)
密钥格式
私钥 (JWK)
{
"kty": "EC",
"crv": "P-521",
"d": "<base64url-encoded-private-key>",
"x": "<base64url-encoded-x-coordinate>",
"y": "<base64url-encoded-y-coordinate>",
"ext": true
}
公钥 (Hex)
<x-coordinate-132-hex-chars><y-coordinate-132-hex-chars>
总长度:264 个十六进制字符(132 字节)
跨平台兼容性
此库设计为与以下平台兼容:
- ✅ JavaScript/TypeScript: Web Crypto API
- ✅ Flutter/Dart: pointycastle 库
- ✅ Node.js: crypto 模块
- ✅ 其他 C# 应用: 本库
与 JavaScript 互操作示例
JavaScript 端签名
// JavaScript 端生成密钥对并签名
async function signInJavaScript() {
// 生成密钥对
const keyPair = await crypto.subtle.generateKey(
{
name: "ECDSA",
namedCurve: "P-521"
},
true,
["sign", "verify"]
);
// 导出私钥为 JWK
const privateKeyJwk = await crypto.subtle.exportKey("jwk", keyPair.privateKey);
// 导出公钥为 raw 格式
const publicKeyRaw = await crypto.subtle.exportKey("raw", keyPair.publicKey);
const publicKeyHex = Array.from(new Uint8Array(publicKeyRaw))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
// 对消息进行签名
const message = "Cross-platform message";
const messageBytes = new TextEncoder().encode(message);
const signatureBytes = await crypto.subtle.sign(
{
name: "ECDSA",
hash: "SHA-512"
},
keyPair.privateKey,
messageBytes
);
// 转换签名为十六进制
const signature = Array.from(new Uint8Array(signatureBytes))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
return {
privateKeyJwk,
publicKeyHex: publicKeyHex.substring(2), // 去掉 0x04 前缀
signature,
message
};
}
C# 端验证签名
using CSharpCryptoUtils;
public class JavaScriptInteropExample
{
public static async Task Main()
{
// 从 JavaScript 接收的数据
string publicKeyHex = "..."; // JavaScript 导出的公钥(264个十六进制字符)
string signature = "..."; // JavaScript 生成的签名
string message = "Cross-platform message";
// 导入公钥
var publicKey = await PublicKey.FromHexStringAsync(publicKeyHex);
// 验证签名
bool isValid = await publicKey.VerifyAsync(signature, message);
if (isValid)
{
Console.WriteLine("✓ JavaScript 签名验证成功!");
}
else
{
Console.WriteLine("✗ JavaScript 签名验证失败!");
}
}
}
完整的跨平台工作流程
// 1. JavaScript 端:生成密钥并签名
const { publicKeyHex, signature, message } = await signInJavaScript();
// 2. 发送给 C# 后端
const response = await fetch('/api/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
publicKey: publicKeyHex,
signature: signature,
message: message
})
});
const result = await response.json();
console.log('验证结果:', result.isValid); // true
// 3. C# 后端:API 端点接收并验证
[ApiController]
[Route("api")]
public class VerifyController : ControllerBase
{
[HttpPost("verify")]
public async Task<IActionResult> VerifySignature([FromBody] VerifyRequest request)
{
try
{
// 导入 JavaScript 生成的公钥
var publicKey = await PublicKey.FromHexStringAsync(request.PublicKey);
// 验证 JavaScript 生成的签名
bool isValid = await publicKey.VerifyAsync(request.Signature, request.Message);
return Ok(new { isValid });
}
catch (Exception ex)
{
return BadRequest(new { error = ex.Message });
}
}
}
public record VerifyRequest(string PublicKey, string Signature, string Message);
API 参考
KeyGenerator
| 方法 | 返回值 | 描述 |
|---|---|---|
GenerateKeyPairAsync() |
Task<KeyPair> |
生成新的 ECDSA P-521 密钥对 |
PrivateKey
| 方法 | 参数 | 返回值 | 描述 |
|---|---|---|---|
SignAsync(string) |
data: 要签名的数据 | Task<string> |
对数据进行签名,返回十六进制签名 |
ExportKeyAsJWKStringAsync() |
- | Task<string> |
导出为 JWK JSON 字符串 |
FromJWKStringAsync(string) |
jwkString: JWK 字符串 | Task<PrivateKey> |
从 JWK 导入私钥 |
PublicKey
| 方法 | 参数 | 返回值 | 描述 |
|---|---|---|---|
VerifyAsync(string, string) |
signature: 签名<br>data: 原始数据 | Task<bool> |
验证签名是否有效 |
ExportKeyAsHexStringAsync() |
- | Task<string> |
导出为十六进制字符串 |
FromHexStringAsync(string) |
hexString: 十六进制字符串 | Task<PublicKey> |
从十六进制导入公钥 |
最佳实践
安全性
私钥保护
// ❌ 不要将私钥硬编码在代码中 const string privateKey = "..."; // ✅ 从安全的配置或密钥管理服务读取 var privateKeyJwk = await keyVault.GetSecretAsync("private-key"); var privateKey = await PrivateKey.FromJWKStringAsync(privateKeyJwk);密钥存储
// ✅ 使用操作系统的密钥存储 // Windows: DPAPI // Linux/macOS: Keychain // 或使用专门的密钥管理服务 // - Azure Key Vault // - AWS KMS // - HashiCorp Vault资源释放
// ✅ 使用完毕后释放密钥对象 using var privateKey = await PrivateKey.FromJWKStringAsync(jwk); // ... 使用 privateKey // 自动释放
性能优化
重用密钥对象
// ✅ 在应用程序生命周期中重用密钥对象 public class SignatureService { private readonly PrivateKey _privateKey; public SignatureService(string jwk) { _privateKey = PrivateKey.FromJWKStringAsync(jwk).Result; } public Task<string> SignAsync(string data) { return _privateKey.SignAsync(data); } }批量操作
// ✅ 批量签名多个消息 var messages = new[] { "msg1", "msg2", "msg3" }; var signatures = await Task.WhenAll( messages.Select(msg => privateKey.SignAsync(msg)) );
故障排除
常见错误
"Invalid hex string length"
- 原因:公钥十六进制字符串长度不是 264 个字符
- 解决:确保公钥格式正确(132 字节 = 264 hex chars)
"Invalid JWK: expected EC P-521 key"
- 原因:JWK 不是 P-521 曲线的 EC 密钥
- 解决:检查 JWK 的
crv字段是否为 "P-521"
签名验证失败
- 原因:数据、签名或公钥不匹配
- 解决:确保签名和验证使用相同的数据,公钥与私钥匹配
调试技巧
// 启用详细日志
try
{
var keyPair = await KeyGenerator.GenerateKeyPairAsync();
var signature = await keyPair.PrivateKey.SignAsync(data);
var isValid = await keyPair.PublicKey.VerifyAsync(signature, data);
}
catch (CryptographicException ex)
{
Console.WriteLine($"加密操作失败: {ex.Message}");
Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
}
测试覆盖:
- ✅ 密钥生成
- ✅ 签名与验证
- ✅ 密钥导入/导出
- ✅ 跨平台兼容性
- ✅ 错误处理
依赖项
- .NET 7.0+ (System.Security.Cryptography)
- System.Text.Json (用于 JWK 序列化)
版本历史
1.0.0 (2025-01-04)
- ✨ 初始发布
- 🔐 支持 ECDSA P-521 密钥生成
- ✍️ 数字签名与验证
- 🔄 JWK 和 Hex 格式的密钥导入/导出
- 🌐 跨平台兼容性
许可证
MIT License - 详见 LICENSE 文件
ExWallets Team © 2025
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 was computed. 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.