Discussion:
c# get Private Key from certificate
Federico Verponziani
2014-04-11 10:47:01 UTC
Permalink
Hi all,
I'm struggling with C# BouncyCastle to decrypting CMSEnvelopedData with the
Private key contained in a certificate.

I wrote this two functions in VB.NET

Public Shared Function DecryptData(envelopedSigneddata As Byte()) As Byte()
Dim decodedEnvelopeData As New
CmsEnvelopedData(envelopedSigneddata)
Dim recipients As RecipientInformationStore =
decodedEnvelopeData.GetRecipientInfos()
Dim c As ICollection = recipients.GetRecipients()
Dim recData As Byte() = {}
Dim cert As X.X509Certificate2 = GetSignerCertFromFile()
Dim alg As AsymmetricAlgorithm = cert.PrivateKey

Dim privateKey As AsymmetricKeyParameter =
TransformRSAPrivateKey(cert.PrivateKey)
For Each recipient As KeyTransRecipientInformation In c
Try
recData = recipient.GetContent(privateKey)
Exit For
Catch
End Try
Next
Return recData
End Function

Public Shared Function TransformRSAPrivateKey(privateKey As
AsymmetricAlgorithm) As AsymmetricKeyParameter
Dim prov As RSACryptoServiceProvider = TryCast(privateKey,
RSACryptoServiceProvider)
Dim parameters As RSAParameters =
prov.ExportParameters(True)

Return New RsaPrivateCrtKeyParameters(New BigInteger(1,
parameters.Modulus), New BigInteger(1, parameters.Exponent), New
BigInteger(1, parameters.D), New BigInteger(1, parameters.P), New
BigInteger(1, parameters.Q), New BigInteger(1, parameters.DP), _
New BigInteger(1, parameters.DQ), New BigInteger(1,
parameters.InverseQ))
End Function

I always get this error, “Key not valid for use in specified state" at
Dim parameters As RSAParameters = prov.ExportParameters(True)
both if I take the certificate from the store in this manner

Private Shared Function GetSignerCert() As X.X509Certificate2
Dim storeMy As X.X509Store = New X.X509Store(X.StoreName.My,
X.StoreLocation.LocalMachine)

storeMy.Open(X.OpenFlags.ReadOnly)
Dim certColl As X.X509Certificate2Collection =
storeMy.Certificates.Find(X.X509FindType.FindBySubjectName,
CLIENT_CERTIFICATE__CN, False)
If certColl.Count = 0 Then
Throw New Exception("Cert not found.")
End If
storeMy.Close()
Return certColl(0)
End Function

or if I take it directly from the file in this manner

Private Shared Function GetSignerCertFromFile() As X.X509Certificate2
Dim cert As X.X509Certificate2 = New
X.X509Certificate2(GlobalsVariablesFunctions.CertsPath +
CLIENT_CERTIFICATE_FILENAME, "password",
X509Certificates.X509KeyStorageFlags.MachineKeySet)
Return cert
End Function

I've already followed articles suggesting to empty RSA folders in user's
profile and Program Files and restarting IIS, but with no luck.

I've seen in Java there are classe like KeyStore and PrivateKey, but in C#
they don't.
How can I get the PrivateKey from the certificate in C# with BouncyCastle?

Thanks in advance

Loading...