2017-04-11 51 views
0

我試圖生成PFX證書,並使用C# 我一直在使用充氣城堡庫使用下面的代碼簽約使用所生成的RSA密鑰對充氣城堡

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格式簽署再然後,我簽署了CSR並獲得PEM證書,並把它放在旁邊私鑰PEM然後用下面的代碼

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文件我籤它保存到PFX文件生成,我得到了下面的錯誤 「無效的算法指定」

簽署代碼

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

最後我想通了答案, 我不得不爲簽名方法的代碼更改爲

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; 
    } 
+0

感謝您報告但是如果您需要先編碼然後解碼數據,那麼看起來還有其他問題(如果密鑰位於智能卡或HSM中,則上述代碼無法工作)。可能關鍵是不允許首先簽署證書?這由證書中的密鑰使用位決定。 –