2017-04-11 2 views
0

je suis en train de générer un certificat .pfx et signer avec l'aide de C# j'ai réussi à produire la clé RSE et privé au format pem en utilisant la bibliothèque du château Bouncy en utilisant le code suivantsignature en utilisant Généré RSA KeyPair Bouncy Castle

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); 
     } 
    } 

alors je signé le CSR et obtenu le certificat .pem et l'a placé à côté de la pem clé privée puis enregistré dans le fichier PFX à l'aide du code ci-dessous

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(); 
    } 

mon problème est quand je suis en train de signer en utilisant le fichier PFX i généré, j'ai l'erreur ci-dessous « algorithme invalide spécifié »

code signature

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

Répondre

0

finalement je me suis dit la réponse, je devais changer le code de la méthode de signature à

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

Merci de nous signaler retour, mais si vous devez d'abord encoder puis décoder les données, alors il semble que quelque chose d'autre est faux (si la clé est dans une carte à puce ou HSM le code ci-dessus ne peut jamais fonctionner). Probablement la clé n'est pas autorisée à signer des certificats en premier lieu? Ceci est déterminé par les bits d'utilisation de clé dans le certificat. –