【问题标题】:How to get private key from PKCS#12 (.p12) file using C#如何使用 C# 从 PKCS#12 (.p12) 文件中获取私钥
【发布时间】:2011-07-25 05:02:39
【问题描述】:

我正在尝试使用 PKCS#12 证书对一些数据进行签名,但是我无法从 PKCS#12 (.p12) 文件中获取私钥。

    public byte[] sign(string text)
    {
        string password = "1111";
        X509Certificate2 cert = new X509Certificate2("c:\\certificate.p12",password);
        byte[] certData = cert.Export(X509ContentType.Pfx,password);

        X509Certificate2 newCert = new X509Certificate2(certData, password);
        RSACryptoServiceProvider crypt = (RSACryptoServiceProvider)newCert.PrivateKey;

        SHA1Managed sha1 = new SHA1Managed();
        UnicodeEncoding encoding = new UnicodeEncoding();
        byte[] data = encoding.GetBytes(text);
        byte[] hash = sha1.ComputeHash(data);
        return crypt.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
    }

问题是 newCert.PrivateKey 为空,但如果我以类似的方式使用 .pfx 证书,它可以工作。

    public byte[] sign(string text)
    {
        string password = "1234";
        X509Certificate2 cert = new X509Certificate2("c:\\certificate.pfx", password);
        RSACryptoServiceProvider crypt = (RSACryptoServiceProvider)cert.PrivateKey;
        SHA1Managed sha1 = new SHA1Managed();
        UnicodeEncoding encoding = new UnicodeEncoding();
        byte[] data = encoding.GetBytes(text);
        byte[] hash = sha1.ComputeHash(data);
        return crypt.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
    }

那么问题是如何从 .p12 文件中获取该私钥?

【问题讨论】:

  • 您是否为 .PFX 和 .P12 尝试过相同的代码?根据你从哪里得到 P12,我相信它应该是一样的。

标签: c# encryption x509certificate2 pkcs#12


【解决方案1】:

看看this question。它看起来非常相似。

【讨论】:

  • 嗨@Timores。感谢您提供链接,但该问题的解决方案显然对我不起作用。
【解决方案2】:

docs中,它说.export()不支持Pfx类型,只支持CertSerializedCertPkcs12

【讨论】:

    【解决方案3】:

    我有一个类似的问题,我发布了here,虽然对你来说不是一回事,但问题也可能是权限。
    我的建议是,首先,您必须确保(我想您已经这样做了)私钥是可导出的,并且您拥有该文件的权限。
    接下来,尝试将内容类型导出为X509ContentType.Pkcs12 而不是X509ContentType.Pfx
    最后,如果可能的话,为什么不尝试将其导入到 certstore。我相信这样更安全。步骤在上面的链接中。

    【讨论】:

    • 感谢您的回答。权限不是问题,与不可导出的密钥相同。我尝试将类型更改为X509ContentType.Pkcs12,但结果相同。尽管将其导入 certstore 可能是一个解决方案。
    【解决方案4】:

    这是为使用 Android 完成的 - 所以下面的 R.raw.key 是我在 Android Raw 文件夹中的文件。

    我将 key.p12 作为输入流打开。然后我使用示例中的库将其转换为私钥。

    http://www.flexiprovider.de/examples/ExampleSMIMEsign.html

    我的代码是这样的

    Security.addProvider(new de.flexiprovider.core.FlexiCoreProvider());
        // Next, we have to read the private PKCS #12 file, since the the
        // private key used for signing is contained in this file:
        DERDecoder dec = new DERDecoder(getResources().openRawResource(
                R.raw.key));
        PFX pfx = new PFX();
        try {
            pfx.decode(dec);
            SafeBag safeBag = pfx.getAuthSafe().getSafeContents(0)
                    .getSafeBag(0);
            PKCS8ShroudedKeyBag kBag = (PKCS8ShroudedKeyBag) safeBag
                    .getBagValue();
            char[] password = "my password for the p12".toCharArray();
            privKey = kBag.getPrivateKey(password);
            new AsyncLoadStorage(this).execute();
        } catch (ASN1Exception e) {
    

    【讨论】:

    • 我相信它在 Java 中。当我编写该程序时,我需要它在 C# 中执行此操作,但感谢分享。
    猜你喜欢
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    相关资源
    最近更新 更多