更新标准库UDP等

This commit is contained in:
2025-11-11 16:51:37 +08:00
parent 2ebbad09bc
commit bf464b04a6
9 changed files with 479 additions and 607 deletions

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
@@ -11,39 +12,143 @@ namespace Ramitta.lib
public class CryptoHelper
{
/// <summary>
/// 生成RSA密钥对
/// 通过OpenSSH格式私钥计算公钥Base64格式
/// </summary>
/// <param name="keySize">密钥长度通常为2048、4096</param>
/// <returns>包含公钥和私钥的元组</returns>
public static (string publicKey, string privateKey) GenerateKeyPair(int keySize = 2048)
{
try
{
using (var rsa = RSA.Create(keySize))
{
string publicKey = rsa.ToXmlString(false);
string privateKey = rsa.ToXmlString(true);
return (publicKey, privateKey);
}
}
catch (Exception ex)
{
MessageBox.Show($"密钥生成失败: {ex.Message}");
return (null, null);
}
}
/// <summary>
/// 使用私钥对数据进行签名
/// </summary>
public static string? SignData(string data, string privateKey)
/// <param name="openSshPrivateKey">OpenSSH格式的Base64私钥不带PEM头尾</param>
/// <returns>Base64格式的公钥失败返回null</returns>
public static string? GetPublicKeyFromPrivate(string openSshPrivateKey)
{
try
{
using (var rsa = RSA.Create())
{
rsa.FromXmlString(privateKey);
// 解析OpenSSH私钥格式
ImportOpenSshPrivateKey(rsa, openSshPrivateKey);
// 导出公钥为Base64
byte[] publicKeyBytes = rsa.ExportRSAPublicKey();
return Convert.ToBase64String(publicKeyBytes);
}
}
catch (Exception ex)
{
MessageBox.Show($"从私钥提取公钥失败: {ex.Message}");
return null;
}
}
/// <summary>
/// 导入OpenSSH格式的私钥纯Base64编码
/// </summary>
private static void ImportOpenSshPrivateKey(RSA rsa, string openSshBase64)
{
byte[] keyData = Convert.FromBase64String(openSshBase64);
using (var reader = new BinaryReader(new MemoryStream(keyData)))
{
// 读取魔术字
var magic = reader.ReadBytes(15);
string magicString = Encoding.ASCII.GetString(magic);
if (magicString != "openssh-key-v1\0")
throw new FormatException("无效的OpenSSH私钥格式");
// 读取加密信息
var cipherName = ReadLengthPrefixedString(reader);
var kdfName = ReadLengthPrefixedString(reader);
var kdfOptions = ReadLengthPrefixedData(reader);
// 检查是否加密
if (cipherName != "none" || kdfName != "none")
throw new FormatException("不支持加密的OpenSSH私钥");
// 读取密钥数量
var keyCount = ReadUInt32BigEndian(reader);
if (keyCount != 1)
throw new FormatException("不支持多个密钥");
// 读取公钥(跳过)
var publicKey = ReadLengthPrefixedData(reader);
// 读取私钥数据
var privateKeyData = ReadLengthPrefixedData(reader);
// 解析私钥数据
using (var privateReader = new BinaryReader(new MemoryStream(privateKeyData)))
{
// 检查字节序标记
var check1 = privateReader.ReadUInt32();
var check2 = privateReader.ReadUInt32();
if (check1 != check2)
throw new FormatException("私钥检查值不匹配");
// 读取密钥类型
var keyType = ReadLengthPrefixedString(privateReader);
if (keyType != "ssh-rsa")
throw new FormatException("非RSA密钥");
// 读取RSA参数
var modulus = ReadLengthPrefixedData(privateReader); // n
var publicExponent = ReadLengthPrefixedData(privateReader); // e
var privateExponent = ReadLengthPrefixedData(privateReader); // d
var coefficient = ReadLengthPrefixedData(privateReader); // iqmp
var prime1 = ReadLengthPrefixedData(privateReader); // p
var prime2 = ReadLengthPrefixedData(privateReader); // q
// 创建RSA参数并导入
var rsaParameters = new RSAParameters
{
Modulus = modulus,
Exponent = publicExponent,
D = privateExponent,
P = prime1,
Q = prime2,
InverseQ = coefficient
};
rsa.ImportParameters(rsaParameters);
}
}
}
/// <summary>
/// 读取长度前缀字符串
/// </summary>
private static string ReadLengthPrefixedString(BinaryReader reader)
{
var data = ReadLengthPrefixedData(reader);
return Encoding.ASCII.GetString(data);
}
/// <summary>
/// 读取长度前缀数据
/// </summary>
private static byte[] ReadLengthPrefixedData(BinaryReader reader)
{
var length = ReadUInt32BigEndian(reader);
return reader.ReadBytes((int)length);
}
/// <summary>
/// 以大端序读取uint32
/// </summary>
private static uint ReadUInt32BigEndian(BinaryReader reader)
{
var data = reader.ReadBytes(4);
if (BitConverter.IsLittleEndian)
Array.Reverse(data);
return BitConverter.ToUInt32(data, 0);
}
/// <summary>
/// 使用OpenSSH格式私钥对数据进行签名
/// </summary>
public static string? SignDataWithOpenSsh(string data, string openSshPrivateKey)
{
try
{
using (var rsa = RSA.Create())
{
ImportOpenSshPrivateKey(rsa, openSshPrivateKey);
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
byte[] signature = rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
@@ -58,61 +163,15 @@ namespace Ramitta.lib
}
/// <summary>
/// 使用公钥验证签名
/// 使用OpenSSH格式私钥解密数据
/// </summary>
public static bool? VerifySignature(string data, string signature, string publicKey)
public static string? DecryptWithOpenSsh(string encryptedData, string openSshPrivateKey)
{
try
{
using (var rsa = RSA.Create())
{
rsa.FromXmlString(publicKey);
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
byte[] signatureBytes = Convert.FromBase64String(signature);
return rsa.VerifyData(dataBytes, signatureBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
}
catch (Exception ex)
{
return false;
}
}
/// <summary>
/// 使用公钥加密数据
/// </summary>
public static string? Encrypt(string data, string publicKey)
{
try
{
using (var rsa = RSA.Create())
{
rsa.FromXmlString(publicKey);
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
byte[] encryptedBytes = rsa.Encrypt(dataBytes, RSAEncryptionPadding.OaepSHA256);
return Convert.ToBase64String(encryptedBytes);
}
}
catch (Exception ex)
{
return null;
}
}
/// <summary>
/// 使用私钥解密数据
/// </summary>
public static string? Decrypt(string encryptedData, string privateKey)
{
try
{
using (var rsa = RSA.Create())
{
rsa.FromXmlString(privateKey);
ImportOpenSshPrivateKey(rsa, openSshPrivateKey);
byte[] encryptedBytes = Convert.FromBase64String(encryptedData);
byte[] decryptedBytes = rsa.Decrypt(encryptedBytes, RSAEncryptionPadding.OaepSHA256);
@@ -125,5 +184,79 @@ namespace Ramitta.lib
return null;
}
}
/// <summary>
/// 获取OpenSSH格式私钥的密钥长度
/// </summary>
public static int GetOpenSshKeySize(string openSshPrivateKey)
{
try
{
using (var rsa = RSA.Create())
{
ImportOpenSshPrivateKey(rsa, openSshPrivateKey);
return rsa.KeySize;
}
}
catch (Exception ex)
{
MessageBox.Show($"获取密钥长度失败: {ex.Message}");
return -1;
}
}
// 其他原有方法保持不变...
public static (string publicKey, string privateKey) GenerateKeyPair(int keySize = 2048)
{
try
{
using (var rsa = RSA.Create(keySize))
{
byte[] publicKeyBytes = rsa.ExportRSAPublicKey();
byte[] privateKeyBytes = rsa.ExportRSAPrivateKey();
string publicKey = Convert.ToBase64String(publicKeyBytes);
string privateKey = Convert.ToBase64String(privateKeyBytes);
return (publicKey, privateKey);
}
}
catch (Exception ex)
{
MessageBox.Show($"密钥生成失败: {ex.Message}");
return (null, null);
}
}
public static string? SignData(string data, string privateKey)
{
try
{
using (var rsa = RSA.Create())
{
byte[] privateKeyBytes = Convert.FromBase64String(privateKey);
try
{
rsa.ImportRSAPrivateKey(privateKeyBytes, out _);
}
catch
{
rsa.ImportPkcs8PrivateKey(privateKeyBytes, out _);
}
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
byte[] signature = rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
return Convert.ToBase64String(signature);
}
}
catch (Exception ex)
{
return null;
}
}
// 其他方法...
}
}
}