Createx509certificate2 如何给出证书字节和私钥 - dnx50
How Createx509certificate2 given certificate bytes and private key - dnx50
基本上,我正在使用 LetsEncrypt 服务获取证书字节 [],我可以将其转换为 X509Certificate2,但它缺少私钥,无法在 SSLStream 上使用它。我将私钥作为 RSAParameters,但也可以将其转换为 byte[],但我似乎无法找到将两者放在同一个 X509Certificate2 中的方法,因此我可以将其用于 SSLStream 上的 AuthenticateAsServer。据我所知,您将用于 dotnet 4 的方法似乎不适用于 dnx50。我的工作示例将是完美的,我想将解决方案保留在 dnx50 中,因为我想将其部署到 linux 和 windows 框。
基本上尝试做类似于 Convert Certificate and Private Key to .PFX programatically in C# 的事情,但只是用私钥创建 X509 虽然保存将是我的下一个任务。
据我目前所知,我认为 dnx50 不允许您创建证书对象,然后像 dotnet 4 那样向其添加私钥。相反,我认为我需要传入一个文件或字节[],其中包含这两个文件才能工作,但我不知道如何将我的 2 字节数组合并在一起或格式化它们。
终于找到解决办法了。不理想,但它有效。基本上它使用 bouncyCastle 创建一个 pfx 流,然后您可以读入它以加载带有证书的私钥。为了在 CoreCLR 上做到这一点,我使用了 nuget 包 Portable.BouncyCastle:1.8.1 以及我放入助手 class.
中的以下代码
public X509Certificate2 CreateX509Certificate2(RSAParameters keys, byte[] certificateBytes, string friendlyName)
{
if (string.IsNullOrWhiteSpace(friendlyName))
{
friendlyName = "default";
}
var store = new Pkcs12Store();
var convertedKeys = GetRsaKeyPair(keys);
var certificate = new X509CertificateParser().ReadCertificate(certificateBytes);
store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(convertedKeys.Private), new X509CertificateEntry[] { new X509CertificateEntry(certificate)});
using (MemoryStream ms = new MemoryStream())
{
var random = new SecureRandom();
string password = random.Next().ToString() + random.Next().ToString() + random.Next().ToString();
store.Save(ms, password.ToCharArray(), random);
var cert = new X509Certificate2(ms.ToArray(), password, X509KeyStorageFlags.Exportable);
return cert;
}
}
private AsymmetricCipherKeyPair GetRsaKeyPair(
RSAParameters rp)
{
BigInteger modulus = new BigInteger(1, rp.Modulus);
BigInteger pubExp = new BigInteger(1, rp.Exponent);
RsaKeyParameters pubKey = new RsaKeyParameters(
false,
modulus,
pubExp);
RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
modulus,
pubExp,
new BigInteger(1, rp.D),
new BigInteger(1, rp.P),
new BigInteger(1, rp.Q),
new BigInteger(1, rp.DP),
new BigInteger(1, rp.DQ),
new BigInteger(1, rp.InverseQ));
return new AsymmetricCipherKeyPair(pubKey, privKey);
}
基本上,我正在使用 LetsEncrypt 服务获取证书字节 [],我可以将其转换为 X509Certificate2,但它缺少私钥,无法在 SSLStream 上使用它。我将私钥作为 RSAParameters,但也可以将其转换为 byte[],但我似乎无法找到将两者放在同一个 X509Certificate2 中的方法,因此我可以将其用于 SSLStream 上的 AuthenticateAsServer。据我所知,您将用于 dotnet 4 的方法似乎不适用于 dnx50。我的工作示例将是完美的,我想将解决方案保留在 dnx50 中,因为我想将其部署到 linux 和 windows 框。
基本上尝试做类似于 Convert Certificate and Private Key to .PFX programatically in C# 的事情,但只是用私钥创建 X509 虽然保存将是我的下一个任务。
据我目前所知,我认为 dnx50 不允许您创建证书对象,然后像 dotnet 4 那样向其添加私钥。相反,我认为我需要传入一个文件或字节[],其中包含这两个文件才能工作,但我不知道如何将我的 2 字节数组合并在一起或格式化它们。
终于找到解决办法了。不理想,但它有效。基本上它使用 bouncyCastle 创建一个 pfx 流,然后您可以读入它以加载带有证书的私钥。为了在 CoreCLR 上做到这一点,我使用了 nuget 包 Portable.BouncyCastle:1.8.1 以及我放入助手 class.
中的以下代码public X509Certificate2 CreateX509Certificate2(RSAParameters keys, byte[] certificateBytes, string friendlyName)
{
if (string.IsNullOrWhiteSpace(friendlyName))
{
friendlyName = "default";
}
var store = new Pkcs12Store();
var convertedKeys = GetRsaKeyPair(keys);
var certificate = new X509CertificateParser().ReadCertificate(certificateBytes);
store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(convertedKeys.Private), new X509CertificateEntry[] { new X509CertificateEntry(certificate)});
using (MemoryStream ms = new MemoryStream())
{
var random = new SecureRandom();
string password = random.Next().ToString() + random.Next().ToString() + random.Next().ToString();
store.Save(ms, password.ToCharArray(), random);
var cert = new X509Certificate2(ms.ToArray(), password, X509KeyStorageFlags.Exportable);
return cert;
}
}
private AsymmetricCipherKeyPair GetRsaKeyPair(
RSAParameters rp)
{
BigInteger modulus = new BigInteger(1, rp.Modulus);
BigInteger pubExp = new BigInteger(1, rp.Exponent);
RsaKeyParameters pubKey = new RsaKeyParameters(
false,
modulus,
pubExp);
RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
modulus,
pubExp,
new BigInteger(1, rp.D),
new BigInteger(1, rp.P),
new BigInteger(1, rp.Q),
new BigInteger(1, rp.DP),
new BigInteger(1, rp.DQ),
new BigInteger(1, rp.InverseQ));
return new AsymmetricCipherKeyPair(pubKey, privKey);
}