我正在尝试使用c#生成pfx证书并签名 我使用以下代码
使用Bouncy城堡库成功地将CSR和私钥生成为pem格式 private void GeneratePkcs10
(string domainName, string companyName, string division, string city, string state,
string countryIso2Characters, string email, RootLenght rootLength, out string csr, out string privateKey)
{
csr = null;
privateKey = null;
try
{
var rsaKeyPairGenerator = new RsaKeyPairGenerator();
// Note: the numbers {3, 5, 17, 257 or 65537} as Fermat primes.
// NIST doesn't allow a public exponent smaller than 65537, since smaller exponents are a problem if they aren't properly padded.
// Note: the default in openssl is '65537', i.e. 0x10001.
var genParam = new RsaKeyGenerationParameters
(BigInteger.ValueOf(0x10001), new SecureRandom(), (int)rootLength, 256);
rsaKeyPairGenerator.Init(genParam);
AsymmetricCipherKeyPair pair = rsaKeyPairGenerator.GenerateKeyPair();
var attributes = new Dictionary<DerObjectIdentifier, string>
{
{ X509Name.CN, domainName },
{ X509Name.O, companyName },
{ X509Name.L, city },
{ X509Name.ST, state },
{ X509Name.C, countryIso2Characters }
};
if (division != null)
{
attributes.Add(X509Name.OU, division);
}
if (email != null)
{
attributes.Add(X509Name.EmailAddress, email);
}
var subject = new X509Name(attributes.Keys.ToList(), attributes);
var pkcs10CertificationRequest = new Pkcs10CertificationRequest
(PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id, subject, pair.Public, null, pair.Private);
csr = Convert.ToBase64String(pkcs10CertificationRequest.GetEncoded());
string certificateRequest = "-----BEGIN CERTIFICATE REQUEST-----" + Environment.NewLine;
// TxtPkcSvalue.Text;
IEnumerable<string> csrData = ChunksUpto(csr, 63);
for (int i = 0; i < csrData.ToArray().Length; i++)
{
certificateRequest += csrData.ToArray()[i] + Environment.NewLine; ;
}
certificateRequest += "-----END CERTIFICATE REQUEST-----" + Environment.NewLine;
File.WriteAllText("E:/CSR.txt", certificateRequest);
string pemObject = GetPEMStringFromRSAKeyPair(pair);
File.WriteAllText("E:/PrivateKey.pem", pemObject);
string publicpemObject = GetPublicPEMStringFromRSAKeyPair(pair);
File.WriteAllText("E:/PublicKey.pem", publicpemObject);
MessageBox.Show("CSR Generated Successfully");
}
catch (Exception ex)
{
// Note: handles errors on the page. Redirect to error page.
MessageBox.Show(ex.Message);
}
}
然后我签署了CSR并获得了pem证书并将其放在私钥pem旁边,然后使用以下代码将其保存到pfx文件中
private void SavePFX()
{
StreamReader sr = File.OpenText(@"E:/PrivateKey.pem");
PemReader pemReader = new PemReader(sr);
Pkcs12Store store = new Pkcs12StoreBuilder().Build();
X509CertificateEntry[] chain = new X509CertificateEntry[1];
AsymmetricCipherKeyPair privKey = null;
object o;
while ((o = pemReader.ReadObject()) != null)
{
if (o is X509Certificate)
{
chain[0] = new X509CertificateEntry((X509Certificate)o);
}
else if (o is AsymmetricCipherKeyPair)
{
privKey = (AsymmetricCipherKeyPair)o;
}
}
store.SetKeyEntry("test", new AsymmetricKeyEntry(privKey.Private), chain);
FileStream p12file = File.Create("localhost.p12");
store.Save(p12file, "12345".ToCharArray(), new SecureRandom());
p12file.Close();
}
我的问题是当我尝试使用我生成的PFX文件进行签名时,我收到了以下错误 &#34;指定了无效算法&#34;
签署代码
public byte[] SignData(string subject, byte[] data, string hashAlgorithm)
{
X509Certificate2 certificate = GetCertificatesFromFolderPath(subject);
var privateKey = certificate.PrivateKey as RSACryptoServiceProvider;
if (!certificate.HasPrivateKey)
throw new Exception("The certificate does not have a private key");
switch (hashAlgorithm)
{
case "SHA-256":
hashAlgorithm = "SHA256";
break;
case "SHA-1":
hashAlgorithm = "SHA1";
break;
}
if (privateKey != null) return privateKey.SignData(data, CryptoConfig.MapNameToOID("SHA256"));
return null;
}
答案 0 :(得分:0)
最后我想出了答案, 我不得不将签名方法的代码更改为
public byte[] SignData(string subject, byte[] data, string hashAlgorithm)
{
X509Certificate2 certificate = GetCertificatesFromFolderPath(subject);
var privateKey = new RSACryptoServiceProvider();
if (!certificate.HasPrivateKey)
throw new Exception("The certificate does not have a private key");
switch (hashAlgorithm)
{
case "SHA-256":
hashAlgorithm = "SHA256";
break;
case "SHA-1":
hashAlgorithm = "SHA1";
break;
}
privateKey.FromXmlString(certificate.PrivateKey.ToXmlString(true));
return privateKey.SignData(data, CryptoConfig.MapNameToOID("SHA256"));
return null;
}