我正在为 DocuSign 的 API 构建自己的 .NET Standard 2.0 库,我需要从它们生成的公钥和私钥字符串中获取
RSA
实例,以便我可以创建 JWT。当我在 LINQPad 中对此进行原型设计时,我具有使用 .NET 7 运行时和 RSA.ImportFromPem()
的优势,但这在 .NET Standard 2.0 中不可用。
我尝试使用 Bouncy Castle 想出一些东西,但这是我第一次使用该库,而且我不太精通密码学。
如何获取公钥或私钥的字符串输入并获取
RSA
实例以便稍后用于 JWT 生成?
该库必须是 .NET Standard 2.0,因为将使用它的项目位于 .NET Framework 4.8 上。
我正在使用的字符串示例:
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAwvyMB2MwWJ1TG2iTbozZOovSAEeUBg6dpqz+pGhwf0ll3OU1
...
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwvyMB2MwWJ1TG2iTbozZ
...
-----END PUBLIC KEY-----
我也不想将字符串保存到文件中,然后读取它们,然后删除它们。 API 文档指出 JWT 必须每 45 分钟重新生成一次,我宁愿将字符串保存在内存中并根据需要使用它们。
发布的私钥是 PKCS#1 格式的 PEM 编码密钥,公钥是 X.509/SPKI 格式的 PEM 编码密钥。
与这篇文章非常类似,但它指的是.NET Core 2.2,C#/BouncyCastle也可用于.NET Framework(尤其是.NET Standard 2)来导入PEM密钥:
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System.IO;
using System.Security.Cryptography;
public static RSA ImportFromPem(string pem, bool isPrivate)
{
PemReader pemReader = new PemReader(new StringReader(pem));
object key = pemReader.ReadObject();
RSAParameters rsaParameters = isPrivate ?
DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)(((AsymmetricCipherKeyPair)key).Private)) :
DotNetUtilities.ToRSAParameters((RsaKeyParameters)key);
RSA rsa = RSA.Create();
rsa.ImportParameters(rsaParameters);
return rsa;
}
使用 Portable.BouncyCastle 用于 .Net Framework 4、.NET Standard 2.0。
使用示例:
// Note: 512-bit keys only for test purposes; nowadays at least 2048-bit keys must be used!
string privateKeyPkcs1Pem = @"-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBALWDYiRs0Q209/tUtdaYP5hvPs76U6U68kJcRntz2anwtvCURhhY
dAZ6GDK8jQOREzlkTGRHxlj9NVb/zNp4PdECAwEAAQJAZ6Di3zjhAZpYGb17M1Eo
vbaFfVWde6/zr79O3hx+IG6/O/OLZIbNd6Zx9+JFrGyLFHxwNFvdaDHK1+H1gqhp
gQIhAN7nvzgc2EFtHyPaffYC23qgzwLabFV+BrjX/sbpao6dAiEA0HZlA78OqWL5
yX92DdfqeXG5U363y7BwQMSKX59Ky8UCIGXbKgK/E4aaEX+1qJdQ6O/ZKZ8ZJiXO
x82RTaehI4L1AiEAjjspgtvZuhKw0R1pQ9q8vW2tf91ms9BHVrmCm+mIU+0CIFqP
A3B8EIajouhnjedvunRAh71d0kIjuZE7GUSwqMP1
-----END RSA PRIVATE KEY-----";
string publicKeySPKIPem = @"-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALWDYiRs0Q209/tUtdaYP5hvPs76U6U6
8kJcRntz2anwtvCURhhYdAZ6GDK8jQOREzlkTGRHxlj9NVb/zNp4PdECAwEAAQ==
-----END PUBLIC KEY-----";
RSA privateKey = ImportFromPem(privateKeyPkcs1Pem, true);
RSA publicKey = ImportFromPem(publicKeySPKIPem, false);
byte[] ciphertext = publicKey.Encrypt(Encoding.UTF8.GetBytes("The quick brown fox jumps over the lazy dog"), RSAEncryptionPadding.Pkcs1);
byte[] decrypted = privateKey.Decrypt(ciphertext, RSAEncryptionPadding.Pkcs1);
Console.WriteLine(Encoding.UTF8.GetString(decrypted)); // The quick brown fox jumps over the lazy dog