title: Signing X509 Certs w/BouncyCastle - invalid digital signature
body: <blockquote>
    <p><strong>Possible Duplicate:</strong><br>
    <a href="https://stackoverflow.com/questions/4659641/generated-signed-x-509-client-certificate-is-invalid-no-certificate-chain-to-it">Generated signed X.509 client certificate is invalid (no certificate chain to its CA)</a>  </p>
  </blockquote>
  
  
  
  <p>I followed the example at:</p>
  
  <p><a href="http://www.bouncycastle.org/wiki/display/JA1/X.509+Public+Key+Certificate+and+Certification+Request+Generation" rel="nofollow noreferrer">http://www.bouncycastle.org/wiki/display/JA1/X.509+Public+Key+Certificate+and+Certification+Request+Generation</a></p>
  
  <p>But the resulting signed client certificate has the following error when opened in windows:</p>
  
  <p>"This file is invalid for use as the following: Security Certificate"</p>
  
  <p>If I install it anyway and view it with certmgr, the certification path looks OK - I see my self-signed Certificate Authority (which is fine, no problems there) but the client cert has the following status:</p>
  
  <p>"This certificate has an invalid digital signature."</p>
  
  <p>If I call X509Certificate.Verify() it throws the following exception:</p>
  
  <p>"Public key presented not for certificate signature"</p>
  
  <p>Yet I'm using the same exact public key extracted from the Pkcs10CertificationRequest and when I called Verify() on that it's fine.</p>
  
  <p>Any ideas? After days of struggling through this, I've got all the pieces working except this last one - and what's really confusing is that my self-signed CA cert is fine. There's just something going on with the client cert. Here's the entire block of code:</p>
  
  <pre><code>        TextReader textReader = new StreamReader("certificaterequest.pkcs10");
          PemReader pemReader = new PemReader(textReader);
  
          Pkcs10CertificationRequest certificationRequest = (Pkcs10CertificationRequest)pemReader.ReadObject();
          CertificationRequestInfo certificationRequestInfo = certificationRequest.GetCertificationRequestInfo();
          SubjectPublicKeyInfo publicKeyInfo = certificationRequestInfo.SubjectPublicKeyInfo;
  
          RsaPublicKeyStructure publicKeyStructure = RsaPublicKeyStructure.GetInstance(publicKeyInfo.GetPublicKey());
  
          RsaKeyParameters publicKey = new RsaKeyParameters(false, publicKeyStructure.Modulus, publicKeyStructure.PublicExponent);
  
          bool certIsOK = certificationRequest.Verify(publicKey);
          // public key is OK here...
  
          // get the server certificate
          Org.BouncyCastle.X509.X509Certificate serverCertificate = DotNetUtilities.FromX509Certificate(System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile("servermastercertificate.cer"));
  
          // get the server private key
          byte[] privateKeyBytes = File.ReadAllBytes("serverprivate.key");
          AsymmetricKeyParameter serverPrivateKey = PrivateKeyFactory.CreateKey(privateKeyBytes);
  
          // generate the client certificate
          X509V3CertificateGenerator generator = new X509V3CertificateGenerator();
  
          generator.SetSerialNumber(BigInteger.ProbablePrime(120, new Random()));
          generator.SetIssuerDN(serverCertificate.SubjectDN);
          generator.SetNotBefore(DateTime.Now);
          generator.SetNotAfter(DateTime.Now.AddYears(5));
          generator.SetSubjectDN(certificationRequestInfo.Subject);
          generator.SetPublicKey(publicKey);
          generator.SetSignatureAlgorithm("SHA512withRSA");
          generator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(serverCertificate));
          generator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(publicKey));
  
          var newClientCert = generator.Generate(serverPrivateKey);
  
          newClientCert.Verify(publicKey); // &lt;-- this blows up
  
          return DotNetUtilities.ToX509Certificate(newClientCert).Export(X509ContentType.Pkcs12, "user password");
  </code></pre>