/// <summary> /// Export the certificate public and private key details. /// </summary> /// <param name="output">The stream to write the data to.</param> /// <param name="certificate">The certificate to export.</param> public void ExportCertificatePem(TextWriter output, X509Certificate2 certificate) { // Convert X509Certificate2 to X509.X509Certificate Key.X509.X509CertificateParser certParser = new Key.X509.X509CertificateParser(); Key.X509.X509Certificate certBouncy = certParser.ReadCertificate(certificate.RawData); // Write the public and private key pem Key.OpenSsl.PemWriter pemWriter = new Key.OpenSsl.PemWriter(output); pemWriter.WriteObject(certBouncy.GetPublicKey()); // If the certificate has a private key. if (certificate.HasPrivateKey) { string pemPrivateKeyData = certificate.PrivateKey.ToXmlString(true); byte[] pemPrivateKeyList = Encoding.Default.GetBytes(pemPrivateKeyData); Key.Utilities.IO.Pem.PemObject pemPrivateKey = new Key.Utilities.IO.Pem.PemObject("RSA PRIVATE KEY", pemPrivateKeyList); pemWriter.WriteObject(pemPrivateKey); } }
/// <summary> /// Dispose(bool disposing) executes in two distinct scenarios. /// If disposing equals true, the method has been called directly /// or indirectly by a user's code. Managed and unmanaged resources /// can be disposed. /// If disposing equals false, the method has been called by the /// runtime from inside the finalizer and you should not reference /// other objects. Only unmanaged resources can be disposed. /// </summary> protected virtual void Dispose(bool disposing) { // Check to see if Dispose has already been called. if (!this._disposed) { // Note disposing has been done. _disposed = true; // If disposing equals true, dispose all managed // and unmanaged resources. if (disposing) { } // Call the appropriate methods to clean up // unmanaged resources here. _rsPrivateParam = null; _certificate = null; _subjectDN = null; } }
/// <summary> /// Generate an X509 certificate. /// </summary> /// <param name="privateKey">The private key of the issuer that is signing this certificate.</param> /// <param name="publicKey">The public key of the issuer that is signing this certificate.</param> /// <param name="serialNumber">The certificate serial number.</param> /// <param name="issuerDN">The issuer.</param> /// <param name="subjectDN">The subject.</param> /// <param name="notBefore">Not before date.</param> /// <param name="notAfter">Not after data.</param> /// <param name="publicExponent">The public exponent (e; the public key is now represented as {e, n}).</param> /// <param name="strength">The strength of the cipher.</param> /// <param name="signatureAlgorithm">The signature algorithm to use.</param> /// <returns>The X509 certificate.</returns> public X509Certificate2 Generate(RSACryptoServiceProvider privateKey, RSACryptoServiceProvider publicKey, long serialNumber, Openssl.Subject issuerDN, Openssl.Subject subjectDN, DateTime notBefore, DateTime notAfter, long publicExponent = 3, int strength = 4096, Nequeo.Cryptography.Signing.SignatureAlgorithm signatureAlgorithm = Nequeo.Cryptography.Signing.SignatureAlgorithm.SHA512withRSA) { // Clear the certificate. _certificate = null; _subjectDN = subjectDN; _rsPrivateParam = null; // Create the rsa key paramaters from the strength and public exponent. Key.Crypto.Generators.RsaKeyPairGenerator keyPair = new Key.Crypto.Generators.RsaKeyPairGenerator(); Key.Crypto.Parameters.RsaKeyGenerationParameters keyPairParam = new Key.Crypto.Parameters.RsaKeyGenerationParameters( Key.Math.BigInteger.ValueOf(publicExponent), new Key.Security.SecureRandom(), strength, 25); // Initialise the parameters and generate the public private key pair. keyPair.Init(keyPairParam); Key.Crypto.AsymmetricCipherKeyPair rsaKeyPair = keyPair.GenerateKeyPair(); // Assign the rsa parameters. RSAParameters rsaParam = new RSAParameters(); Key.Crypto.Parameters.RsaKeyParameters rsaPublicParam = (Key.Crypto.Parameters.RsaKeyParameters)rsaKeyPair.Public; _rsPrivateParam = (Key.Crypto.Parameters.RsaPrivateCrtKeyParameters)rsaKeyPair.Private; rsaParam.D = _rsPrivateParam.Exponent.ToByteArrayUnsigned(); rsaParam.DP = _rsPrivateParam.DP.ToByteArrayUnsigned(); rsaParam.DQ = _rsPrivateParam.DQ.ToByteArrayUnsigned(); rsaParam.InverseQ = _rsPrivateParam.QInv.ToByteArrayUnsigned(); rsaParam.P = _rsPrivateParam.P.ToByteArrayUnsigned(); rsaParam.Q = _rsPrivateParam.Q.ToByteArrayUnsigned(); rsaParam.Modulus = _rsPrivateParam.Modulus.ToByteArrayUnsigned(); rsaParam.Exponent = _rsPrivateParam.PublicExponent.ToByteArrayUnsigned(); // Create the encyption provider. RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(); rsaProvider.ImportParameters(rsaParam); // Create a new certificate generator. Key.X509.X509V3CertificateGenerator certGenerator = new Key.X509.X509V3CertificateGenerator(); certGenerator.Reset(); // Set the certificate values. certGenerator.SetSerialNumber(Key.Math.BigInteger.ValueOf(serialNumber)); certGenerator.SetIssuerDN(GetNames(issuerDN)); certGenerator.SetSubjectDN(GetNames(subjectDN)); certGenerator.SetNotBefore(notBefore); certGenerator.SetNotAfter(notAfter); certGenerator.SetPublicKey(rsaPublicParam); certGenerator.SetSignatureAlgorithm(GetSignatureAlgorithm(signatureAlgorithm)); // Export the signer private key parameters. RSAParameters rsaPrivateKeySignerParam = privateKey.ExportParameters(true); Key.Crypto.Parameters.RsaPrivateCrtKeyParameters rsaPrivateKeySigner = new Key.Crypto.Parameters.RsaPrivateCrtKeyParameters( new Key.Math.BigInteger(1, rsaPrivateKeySignerParam.Modulus), new Key.Math.BigInteger(1, rsaPrivateKeySignerParam.Exponent), new Key.Math.BigInteger(1, rsaPrivateKeySignerParam.D), new Key.Math.BigInteger(1, rsaPrivateKeySignerParam.P), new Key.Math.BigInteger(1, rsaPrivateKeySignerParam.Q), new Key.Math.BigInteger(1, rsaPrivateKeySignerParam.DP), new Key.Math.BigInteger(1, rsaPrivateKeySignerParam.DQ), new Key.Math.BigInteger(1, rsaPrivateKeySignerParam.InverseQ) ); // Export the signer public key parameters. RSAParameters rsaPublicKeySignerParam = publicKey.ExportParameters(false); Key.Crypto.Parameters.RsaKeyParameters rsaPublicKeySigner = new Key.Crypto.Parameters.RsaKeyParameters( false, new Key.Math.BigInteger(1, rsaPublicKeySignerParam.Modulus), new Key.Math.BigInteger(1, rsaPublicKeySignerParam.Exponent) ); // Add the extensions certGenerator.AddExtension( Key.Asn1.X509.X509Extensions.SubjectKeyIdentifier, false, new Key.X509.Extension.SubjectKeyIdentifierStructure(rsaPublicParam)); certGenerator.AddExtension( Key.Asn1.X509.X509Extensions.AuthorityKeyIdentifier, false, new Key.X509.Extension.AuthorityKeyIdentifierStructure(rsaPublicKeySigner)); // Create the certificate. _certificate = certGenerator.Generate(rsaPrivateKeySigner); _certificate.CheckValidity(DateTime.UtcNow); _certificate.Verify(rsaPublicKeySigner); byte[] raw = _certificate.GetEncoded(); // Return the certificate. X509Certificate2 x509Certificate2 = new X509Certificate2(raw); x509Certificate2.PrivateKey = rsaProvider; x509Certificate2.FriendlyName = subjectDN.CommonName; return(x509Certificate2); }