如何从.NET标准的PEM文件中使用私钥加载证书 [英] How to load a certificate with private key from PEM files in .NET standard

查看:562
本文介绍了如何从.NET标准的PEM文件中使用私钥加载证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从.NET标准库中的PEM文件加载X509Certificate2。

I'm trying to load an X509Certificate2 from PEM files in a .NET standard library.

我使用openssl创建了一个自签名证书,如下所示:

I created a self-signed certificate using openssl like so:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj /CN=localhost -days 365

我将生成的PEM文件加载到项目中的嵌入式字符串资源中,并尝试加载它们并显示以下代码:

I loaded the resulting PEM files into embedded string resources within the project and am trying to load them with the following code:

private X509Certificate2 GetCertificate()
{
    try
    {
        byte[] pubPem = System.Text.Encoding.UTF8.GetBytes(Properties.Resources.DefaultPublicPem.Trim());
        var cert = new X509Certificate2(pubPem);
        var rsa = GetRSAFromPem(Properties.Resources.DefaultPrivatePem.Trim());
        cert.PrivateKey = rsa;
        return cert;
    }

    catch (Exception ex)
    {
        // ignore errors
        return null;
    }
}

public static RSA GetRSAFromPem(String pemstr)
{
    RSA rsaKey = RSA.Create();
    Func<RSA, RsaKeyParameters, RSA> MakePublicRCSP = (RSA rcsp, RsaKeyParameters rkp) =>
    {
        RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rkp);
        rcsp.ImportParameters(rsaParameters);
        return rsaKey;
    };

    Func<RSA, RsaPrivateCrtKeyParameters, RSA> MakePrivateRCSP = (RSA rcsp, RsaPrivateCrtKeyParameters rkp) =>
    {
        RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rkp);
        rcsp.ImportParameters(rsaParameters);
        return rsaKey;
    };

    PemReader reader = new PemReader(new StringReader(pemstr));
    object kp = reader.ReadObject();

    // If object has Private/Public property, we have a Private PEM
    var hasPrivate = kp.GetType().GetProperty("Private") != null;
    var isPrivate = kp is RsaPrivateCrtKeyParameters;
    return isPrivate ? MakePrivateRCSP(rsaKey, (RsaPrivateCrtKeyParameters)kp) : hasPrivate ? MakePrivateRCSP(rsaKey, (RsaPrivateCrtKeyParameters)(((AsymmetricCipherKeyPair)kp).Private)) : MakePublicRCSP(rsaKey, (RsaKeyParameters)kp);
}

我在Android上对其进行了测试,效果很好。

I tested it on Android and it works great.

在iOS上,我尚未进行测试,但是在UWP上它失败了,并且尝试在证书上设置私钥时遇到了PlatformNotSupported异常。

On iOS I haven't tested yet, but on UWP it fails and I get a PlatformNotSupported Exception while trying to set the PrivateKey on the certificate.

所以我想知道不支持什么,以及我是否做得不正确。

So I'm wondering what's not supported, and whether I'm not doing it right.

推荐答案

,.net核心不支持在现有证书上设置私钥:

According to this, setting the private key on an existing certificate is not supported in .net core:


PrivateKey属性将恢复为netstandard2.0(#12295),但
会被放到.NET上核心。

The PrivateKey property will be back in netstandard2.0 (#12295), but it will throw on set for .NET Core.

set_PrivateKey在.NET Framework
中有很多细微差别(取决于您的使用方式,最终可能会带来$ b $的副作用) b在重新启动计算机后仍然存在),并将该细微差别反映到Windows以外的
平台上完全棘手,这就是为什么我们不
支持它。

set_PrivateKey has a large amount of nuance in .NET Framework (depending on how you use it you can end up with side effects that persist across machine reboots), and mirroring that level of nuance to platforms other than Windows is awfully tricky, which is why we don't support it.

在.NET Core $ b上拥有带有私钥的证书的唯一受支持的方法$ b通过PFX / PKCS12文件(或cert + key对已经通过X509Store与
相关联)。

The only supported way to have a cert with a private key on .NET Core is through a PFX/PKCS12 file (or the cert+key pair to already be associated via X509Store).

因此解决此问题的一种方法是将公共-私有对合并到PFX文件,将其作为资源嵌入,然后从该PFX初始化X509Certificate2。

So one way to solve this was to merge public-private pair to a PFX file, embed it as a resource, and initialize the X509Certificate2 from that PFX.

我最终使用的是在UWP上使用RSACertificateExtensions.CopyWithPrivateKey方法。

Another way, which I ended up using, is to use the method RSACertificateExtensions.CopyWithPrivateKey on UWP.

因此,基本上我最终建立了一个平台特定的接口来加载证书。在UWP上,它是这样实现的:

So basically I ended up building a platform specific interface for loading the certificates. On UWP it was implemented like this:

public class UWPCertificateBuilder : ICertificateBuilder
{
    public X509Certificate2 GetCertificate(X509Certificate2 cert, RSA key)
    {
        return cert.CopyWithPrivateKey(key);
    }
}

在Android上是这样实现的:

On Android it was implemented like this:

public class DroidCertificateBuilder : ICertificateBuilder
{
    public X509Certificate2 GetCertificate(X509Certificate2 cert, RSA key)
    {
        cert.PrivateKey = key;
        return cert;
    }
}

这篇关于如何从.NET标准的PEM文件中使用私钥加载证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆