2022-11-09 20:48:03 +08:00
|
|
|
|
using System;
|
2024-02-05 10:53:54 +08:00
|
|
|
|
using System.IO;
|
2022-05-09 19:28:47 +08:00
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using Org.BouncyCastle.Crypto;
|
|
|
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
2024-02-05 10:53:54 +08:00
|
|
|
|
using Org.BouncyCastle.OpenSsl;
|
2022-05-09 19:28:47 +08:00
|
|
|
|
using Org.BouncyCastle.Security;
|
|
|
|
|
|
|
|
|
|
namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities
|
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
using SKIT.FlurlHttpClient.Primitives;
|
|
|
|
|
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// RSA 算法工具类。
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static class RSAUtility
|
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 填充模式:OAEPwithSHA-256andMGF1Padding。
|
|
|
|
|
/// </summary>
|
|
|
|
|
public const string PADDING_MODE_OAEPWITHSHA1ANDMGF1 = "OAEPWITHSHA1ANDMGF1PADDING";
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 签名算法:SHA-256withRSA。
|
|
|
|
|
/// </summary>
|
|
|
|
|
public const string DIGEST_ALGORITHM_SHA256 = "SHA-256withRSA";
|
2022-05-09 19:28:47 +08:00
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
private static byte[] ConvertPrivateKeyPemToByteArray(string privateKeyPem)
|
2022-11-09 23:02:53 +08:00
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
if (!privateKeyPem.StartsWith("-----BEGIN PRIVATE KEY-----"))
|
|
|
|
|
{
|
|
|
|
|
using (TextReader textReader = new StringReader(privateKeyPem))
|
|
|
|
|
using (PemReader pemReader = new PemReader(textReader))
|
|
|
|
|
{
|
|
|
|
|
object pemObject = pemReader.ReadObject();
|
|
|
|
|
|
|
|
|
|
if (pemObject is AsymmetricCipherKeyPair)
|
|
|
|
|
{
|
|
|
|
|
// PKCS#1 格式
|
|
|
|
|
AsymmetricCipherKeyPair cipherKeyPair = (AsymmetricCipherKeyPair)pemObject;
|
|
|
|
|
using (TextWriter textWriter = new StringWriter())
|
|
|
|
|
using (PemWriter pemWriter = new PemWriter(textWriter))
|
|
|
|
|
{
|
|
|
|
|
Pkcs8Generator pkcs8 = new Pkcs8Generator(cipherKeyPair.Private);
|
|
|
|
|
pemWriter.WriteObject(pkcs8);
|
|
|
|
|
pemWriter.Writer.Close();
|
|
|
|
|
|
|
|
|
|
privateKeyPem = textWriter.ToString()!;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (pemObject is RsaPrivateCrtKeyParameters)
|
|
|
|
|
{
|
|
|
|
|
// PKCS#8 格式
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new NotSupportedException("Private key format is not supported.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
privateKeyPem = privateKeyPem
|
2022-11-09 23:02:53 +08:00
|
|
|
|
.Replace("-----BEGIN PRIVATE KEY-----", string.Empty)
|
|
|
|
|
.Replace("-----END PRIVATE KEY-----", string.Empty);
|
2024-02-05 10:53:54 +08:00
|
|
|
|
privateKeyPem = Regex.Replace(privateKeyPem, "\\s+", string.Empty);
|
|
|
|
|
return Convert.FromBase64String(privateKeyPem);
|
2022-11-09 23:02:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
private static byte[] ConvertPublicKeyPemToByteArray(string publicKeyPem)
|
2022-11-09 23:02:53 +08:00
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
if (!publicKeyPem.StartsWith("-----BEGIN PUBLIC KEY-----"))
|
|
|
|
|
{
|
|
|
|
|
using (TextReader textReader = new StringReader(publicKeyPem))
|
|
|
|
|
using (PemReader pemReader = new PemReader(textReader))
|
|
|
|
|
{
|
|
|
|
|
object pemObject = pemReader.ReadObject();
|
|
|
|
|
if (pemObject is RsaKeyParameters)
|
|
|
|
|
{
|
|
|
|
|
// PKCS#1 或 PKCS#8 格式
|
|
|
|
|
RsaKeyParameters rsaKeyParams = (RsaKeyParameters)pemObject;
|
|
|
|
|
using (TextWriter textWriter = new StringWriter())
|
|
|
|
|
using (PemWriter pemWriter = new PemWriter(textWriter))
|
|
|
|
|
{
|
|
|
|
|
pemWriter.WriteObject(rsaKeyParams);
|
|
|
|
|
pemWriter.Writer.Close();
|
|
|
|
|
|
|
|
|
|
publicKeyPem = textWriter.ToString()!;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new NotSupportedException("Public key format is not supported.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
publicKeyPem = publicKeyPem
|
2022-11-09 23:02:53 +08:00
|
|
|
|
.Replace("-----BEGIN PUBLIC KEY-----", string.Empty)
|
|
|
|
|
.Replace("-----END PUBLIC KEY-----", string.Empty);
|
2024-02-05 10:53:54 +08:00
|
|
|
|
publicKeyPem = Regex.Replace(publicKeyPem, "\\s+", string.Empty);
|
|
|
|
|
return Convert.FromBase64String(publicKeyPem);
|
2022-11-09 23:02:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
private static RsaKeyParameters ParsePrivateKeyToParameters(byte[] privateKeyBytes)
|
2022-11-09 23:02:53 +08:00
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
return (RsaKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static RsaKeyParameters ParsePublicKeyToParameters(byte[] publicKeyBytes)
|
|
|
|
|
{
|
|
|
|
|
return (RsaKeyParameters)PublicKeyFactory.CreateKey(publicKeyBytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static byte[] Sign(RsaKeyParameters rsaPrivateKeyParams, byte[] msgBytes, string digestAlgorithm)
|
|
|
|
|
{
|
|
|
|
|
ISigner signer = SignerUtilities.GetSigner(digestAlgorithm);
|
2022-11-09 23:02:53 +08:00
|
|
|
|
signer.Init(true, rsaPrivateKeyParams);
|
|
|
|
|
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
|
|
|
|
|
return signer.GenerateSignature();
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
private static bool Verify(RsaKeyParameters rsaPublicKeyParams, byte[] msgBytes, byte[] signBytes, string digestAlgorithm)
|
2022-11-09 23:02:53 +08:00
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
ISigner signer = SignerUtilities.GetSigner(digestAlgorithm);
|
2022-11-09 23:02:53 +08:00
|
|
|
|
signer.Init(false, rsaPublicKeyParams);
|
|
|
|
|
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
|
|
|
|
|
return signer.VerifySignature(signBytes);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
private static byte[] DecryptWithECB(RsaKeyParameters rsaPrivateKeyParams, byte[] cipherBytes, string paddingMode)
|
2022-11-09 23:02:53 +08:00
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
IBufferedCipher cipher = CipherUtilities.GetCipher($"RSA/ECB/{paddingMode}");
|
2022-11-09 23:02:53 +08:00
|
|
|
|
cipher.Init(false, rsaPrivateKeyParams);
|
|
|
|
|
return cipher.DoFinal(cipherBytes);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
private static byte[] EncryptWithECB(RsaKeyParameters rsaPublicKeyParams, byte[] msgBytes, string paddingMode)
|
2022-11-09 23:02:53 +08:00
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
IBufferedCipher cipher = CipherUtilities.GetCipher($"RSA/ECB/{paddingMode}");
|
2022-11-09 23:02:53 +08:00
|
|
|
|
cipher.Init(true, rsaPublicKeyParams);
|
|
|
|
|
return cipher.DoFinal(msgBytes);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// <summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// 使用私钥生成签名。
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// </summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// <param name="privateKeyBytes">PKCS#1/PKCS#8 私钥字节数组。</param>
|
2022-11-09 23:02:53 +08:00
|
|
|
|
/// <param name="msgBytes">待签名的数据字节数组。</param>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// <param name="digestAlgorithm">签名算法。(默认值:<see cref="DIGEST_ALGORITHM_SHA256"/>)</param>
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// <returns>签名字节数组。</returns>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
public static byte[] Sign(byte[] privateKeyBytes, byte[] msgBytes, string digestAlgorithm = DIGEST_ALGORITHM_SHA256)
|
2022-05-09 19:28:47 +08:00
|
|
|
|
{
|
2024-01-29 23:12:15 +08:00
|
|
|
|
if (privateKeyBytes is null) throw new ArgumentNullException(nameof(privateKeyBytes));
|
|
|
|
|
if (msgBytes is null) throw new ArgumentNullException(nameof(msgBytes));
|
2022-05-09 19:28:47 +08:00
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
RsaKeyParameters rsaPrivateKeyParams = ParsePrivateKeyToParameters(privateKeyBytes);
|
|
|
|
|
return Sign(rsaPrivateKeyParams, msgBytes, digestAlgorithm);
|
2022-05-09 19:28:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// 使用私钥生成签名。
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// </summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// <param name="privateKeyPem">PKCS#1/PKCS#8 私钥(PEM 格式)。</param>
|
|
|
|
|
/// <param name="message">待签名的数据。</param>
|
|
|
|
|
/// <param name="digestAlgorithm">签名算法。(默认值:<see cref="DIGEST_ALGORITHM_SHA256"/>)</param>
|
|
|
|
|
/// <returns>经过 Base64 编码的签名。</returns>
|
|
|
|
|
public static EncodedString Sign(string privateKeyPem, string message, string digestAlgorithm = DIGEST_ALGORITHM_SHA256)
|
2022-05-09 19:28:47 +08:00
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
if (privateKeyPem is null) throw new ArgumentNullException(nameof(privateKeyPem));
|
2024-01-29 23:12:15 +08:00
|
|
|
|
if (message is null) throw new ArgumentNullException(nameof(message));
|
2022-05-09 19:28:47 +08:00
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
byte[] privateKeyBytes = ConvertPrivateKeyPemToByteArray(privateKeyPem);
|
|
|
|
|
byte[] msgBytes = EncodedString.FromLiteralString(message);
|
|
|
|
|
byte[] signBytes = Sign(privateKeyBytes, msgBytes, digestAlgorithm);
|
|
|
|
|
return EncodedString.ToBase64String(signBytes);
|
2022-05-09 19:28:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// 使用公钥验证签名。
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// </summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// <param name="publicKeyBytes">PKCS#1/PKCS#8 公钥字节数组。</param>
|
|
|
|
|
/// <param name="msgBytes">待验证的数据字节数组。</param>
|
|
|
|
|
/// <param name="signBytes">签名字节数组。</param>
|
|
|
|
|
/// <param name="digestAlgorithm">签名算法。(默认值:<see cref="DIGEST_ALGORITHM_SHA256"/>)</param>
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// <returns>验证结果。</returns>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
public static bool Verify(byte[] publicKeyBytes, byte[] msgBytes, byte[] signBytes, string digestAlgorithm = DIGEST_ALGORITHM_SHA256)
|
2022-05-09 19:28:47 +08:00
|
|
|
|
{
|
2024-01-29 23:12:15 +08:00
|
|
|
|
if (publicKeyBytes is null) throw new ArgumentNullException(nameof(publicKeyBytes));
|
|
|
|
|
if (msgBytes is null) throw new ArgumentNullException(nameof(msgBytes));
|
|
|
|
|
if (signBytes is null) throw new ArgumentNullException(nameof(signBytes));
|
2022-05-09 19:28:47 +08:00
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
RsaKeyParameters rsaPublicKeyParams = ParsePublicKeyToParameters(publicKeyBytes);
|
|
|
|
|
return Verify(rsaPublicKeyParams, msgBytes, signBytes, digestAlgorithm);
|
2022-05-09 19:28:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// 使用公钥验证签名。
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// </summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// <param name="publicKeyPem">PKCS#1/PKCS#8 公钥(PEM 格式)。</param>
|
|
|
|
|
/// <param name="message">待验证的数据。</param>
|
|
|
|
|
/// <param name="encodingSignature">经过编码后的(通常为 Base64)签名。</param>
|
|
|
|
|
/// <param name="digestAlgorithm">签名算法。(默认值:<see cref="DIGEST_ALGORITHM_SHA256"/>)</param>
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// <returns>验证结果。</returns>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
public static bool Verify(string publicKeyPem, string message, EncodedString encodingSignature, string digestAlgorithm = DIGEST_ALGORITHM_SHA256)
|
2022-05-09 19:28:47 +08:00
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
if (publicKeyPem is null) throw new ArgumentNullException(nameof(publicKeyPem));
|
2024-01-29 23:12:15 +08:00
|
|
|
|
if (message is null) throw new ArgumentNullException(nameof(message));
|
2024-02-05 10:53:54 +08:00
|
|
|
|
if (encodingSignature.Value is null) throw new ArgumentNullException(nameof(encodingSignature));
|
2022-05-09 19:28:47 +08:00
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
byte[] publicKeyBytes = ConvertPublicKeyPemToByteArray(publicKeyPem);
|
|
|
|
|
byte[] msgBytes = EncodedString.FromLiteralString(message);
|
|
|
|
|
byte[] signBytes = EncodedString.FromString(encodingSignature, fallbackEncodingKind: EncodingKinds.Base64);
|
|
|
|
|
return Verify(publicKeyBytes, msgBytes, signBytes, digestAlgorithm);
|
2022-05-09 19:28:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 使用私钥基于 ECB 模式解密数据。
|
|
|
|
|
/// </summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// <param name="privateKeyBytes">PKCS#1/PKCS#8 私钥字节数组。</param>
|
|
|
|
|
/// <param name="cipherBytes">待解密的数据字节数组。</param>
|
|
|
|
|
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_OAEPWITHSHA1ANDMGF1"/>)</param>
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// <returns>解密后的数据字节数组。</returns>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
public static byte[] DecryptWithECB(byte[] privateKeyBytes, byte[] cipherBytes, string paddingMode = PADDING_MODE_OAEPWITHSHA1ANDMGF1)
|
2022-05-09 19:28:47 +08:00
|
|
|
|
{
|
2024-01-29 23:12:15 +08:00
|
|
|
|
if (privateKeyBytes is null) throw new ArgumentNullException(nameof(privateKeyBytes));
|
|
|
|
|
if (cipherBytes is null) throw new ArgumentNullException(nameof(cipherBytes));
|
2022-05-09 19:28:47 +08:00
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
RsaKeyParameters rsaPrivateKeyParams = ParsePrivateKeyToParameters(privateKeyBytes);
|
|
|
|
|
return DecryptWithECB(rsaPrivateKeyParams, cipherBytes, paddingMode);
|
2022-05-09 19:28:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 使用私钥基于 ECB 模式解密数据。
|
|
|
|
|
/// </summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// <param name="privateKeyPem">PKCS#1/PKCS#8 私钥(PEM 格式)。</param>
|
|
|
|
|
/// <param name="encodingCipher">经过编码后的(通常为 Base64)待解密数据。</param>
|
|
|
|
|
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_OAEPWITHSHA1ANDMGF1"/>)</param>
|
|
|
|
|
/// <returns>解密后的数据。</returns>
|
|
|
|
|
public static EncodedString DecryptWithECB(string privateKeyPem, EncodedString encodingCipher, string paddingMode = PADDING_MODE_OAEPWITHSHA1ANDMGF1)
|
2022-05-09 19:28:47 +08:00
|
|
|
|
{
|
2024-02-05 10:53:54 +08:00
|
|
|
|
if (privateKeyPem is null) throw new ArgumentNullException(nameof(privateKeyPem));
|
|
|
|
|
if (encodingCipher.Value is null) throw new ArgumentNullException(nameof(encodingCipher));
|
2022-05-09 19:28:47 +08:00
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
byte[] privateKeyBytes = ConvertPrivateKeyPemToByteArray(privateKeyPem);
|
|
|
|
|
byte[] cipherBytes = EncodedString.FromString(encodingCipher, fallbackEncodingKind: EncodingKinds.Base64);
|
|
|
|
|
byte[] plainBytes = DecryptWithECB(privateKeyBytes, cipherBytes, paddingMode);
|
|
|
|
|
return EncodedString.ToLiteralString(plainBytes);
|
2022-05-09 19:28:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 使用公钥基于 ECB 模式加密数据。
|
|
|
|
|
/// </summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// <param name="publicKeyBytes">PKCS#1/PKCS#8 公钥字节数组。</param>
|
|
|
|
|
/// <param name="plainBytes">待加密的数据字节数组。</param>
|
|
|
|
|
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_OAEPWITHSHA1ANDMGF1"/>)</param>
|
2022-05-09 19:28:47 +08:00
|
|
|
|
/// <returns>加密后的数据字节数组。</returns>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
public static byte[] EncryptWithECB(byte[] publicKeyBytes, byte[] plainBytes, string paddingMode = PADDING_MODE_OAEPWITHSHA1ANDMGF1)
|
2022-05-09 19:28:47 +08:00
|
|
|
|
{
|
2024-01-29 23:12:15 +08:00
|
|
|
|
if (publicKeyBytes is null) throw new ArgumentNullException(nameof(publicKeyBytes));
|
|
|
|
|
if (plainBytes is null) throw new ArgumentNullException(nameof(plainBytes));
|
2022-05-09 19:28:47 +08:00
|
|
|
|
|
2024-02-05 10:53:54 +08:00
|
|
|
|
RsaKeyParameters rsaPublicKeyParams = ParsePublicKeyToParameters(publicKeyBytes);
|
|
|
|
|
return EncryptWithECB(rsaPublicKeyParams, plainBytes, paddingMode);
|
2022-05-09 19:28:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 使用公钥基于 ECB 模式加密数据。
|
|
|
|
|
/// </summary>
|
2024-02-05 10:53:54 +08:00
|
|
|
|
/// <param name="publicKeyPem">PKCS#1/PKCS#8 公钥(PEM 格式)。</param>
|
|
|
|
|
/// <param name="plainData">待加密数据。</param>
|
|
|
|
|
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_OAEPWITHSHA1ANDMGF1"/>)</param>
|
|
|
|
|
/// <returns>经过 Base64 编码的加密数据。</returns>
|
|
|
|
|
public static EncodedString EncryptWithECB(string publicKeyPem, string plainData, string paddingMode = PADDING_MODE_OAEPWITHSHA1ANDMGF1)
|
|
|
|
|
{
|
|
|
|
|
if (publicKeyPem is null) throw new ArgumentNullException(nameof(publicKeyPem));
|
|
|
|
|
if (plainData is null) throw new ArgumentNullException(nameof(plainData));
|
|
|
|
|
|
|
|
|
|
byte[] publicKeyBytes = ConvertPublicKeyPemToByteArray(publicKeyPem);
|
|
|
|
|
byte[] plainBytes = EncodedString.FromLiteralString(plainData);
|
|
|
|
|
byte[] cipherBytes = EncryptWithECB(publicKeyBytes, plainBytes, paddingMode);
|
|
|
|
|
return EncodedString.ToBase64String(cipherBytes);
|
2022-05-09 19:28:47 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|