4

我试图使用 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 文件中获取该私钥?

4

4 回答 4

3

I had a similar problem which I posted here, although it is not the same thing for you, the problem may be also permissions.
My suggestions are, first, you have to make sure (which I suppose you already did) that the private key is exportable and you have permissions to the file.
Next, try exporting the content type as X509ContentType.Pkcs12 instead of X509ContentType.Pfx
Finally, if it is possible, why don't you try importing it to the certstore. I believe that's more secure. The steps are in the link above.

于 2011-09-27T18:18:23.493 回答
0

看看这个问题。它看起来非常相似。

于 2011-03-29T11:46:05.713 回答
0

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

于 2011-09-26T03:50:49.277 回答
-1

这是为使用 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) {
于 2012-08-28T10:04:39.317 回答