public void CalculateSignatureShouldSucceed() { // The certificate should exist in the certificate store // on LocalMachine in CA store with appropriate subject CN // as it is defined in with the given "issuerSubject". // This certificate should have an associated private key that may not be exportable. const string issuerSubject = "L2"; var privateKey = new PksEcPrivateKey( issuerSubject, "CA", "LocalMachine"); const string algorithm = "SHA256withECDSA"; ISignatureFactory signatureFactory = new PksAsn1SignatureFactory(algorithm, privateKey); // example of hash, real hash will be a longer byte array byte[] hash = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 }; IStreamCalculator calculator = signatureFactory.CreateCalculator(); using (var stream = calculator.Stream) { stream.Write(hash, 0, hash.Length); } object result = calculator.GetResult(); byte[] signature = ((IBlockResult)result).Collect(); // ASN.1 DER formatted signature Assert.IsNotNull(signature); }
public void CreateCertificateShouldSucceed() { // some public key in base64 DER encoded, that will be used as public key of the new certificate, // it should be ECDSA with SHA256 for this example, since the signing Certificate is also ECDSA with SHA256 (OID 1.2.840.10045.4.3.2) const string publicKey = @"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhpFTpKgGDqfxSwp9WlPJMa2o3XR5x1xKAgC4CR2AFbSzGFAjCIkUKtBCUrA5Te6ydhxVduA3JFE2hzqy/6V6qA=="; // The certificate should exist in the certificate store // on LocalMachine in CA store with appropriate subject CN // as it is defined in with the given "issuerSubject". // This certificate should have an associated private key that may not be exportable. const string issuerSubject = "L2"; var privateKey = new PksEcPrivateKey( issuerSubject, "CA", "LocalMachine"); const string algorithm = "SHA256withECDSA"; ISignatureFactory signatureFactory = new PksAsn1SignatureFactory(algorithm, privateKey); // signatureCalculatorFactory can be used for generating a new certificate with BouncyCastle var certificateGenerator = new X509V3CertificateGenerator(); // ... set all other required fields of the X509V3CertificateGenerator certificateGenerator.SetSerialNumber(BigInteger.One); certificateGenerator.SetIssuerDN(ToX509Name(issuerSubject)); certificateGenerator.SetSubjectDN(ToX509Name("My-new-cert", "My-org")); certificateGenerator.SetPublicKey( PublicKeyFactory.CreateKey( SubjectPublicKeyInfo.GetInstance(Convert.FromBase64String(publicKey)))); certificateGenerator.SetNotBefore(DateTime.Now.Subtract(TimeSpan.FromMinutes(10))); certificateGenerator.SetNotAfter(DateTime.Now.Add(TimeSpan.FromDays(14))); // finally run the generator for a new certificate: X509Certificate cert = certificateGenerator.Generate(signatureFactory); Assert.IsNotNull(cert); }
public X509Certificate CreateCertificate(CertificateDefinition definition) { var randomGenerator = new CryptoApiRandomGenerator(); BigInteger serialNumber = CreateSerialNumber(randomGenerator); if (definition.SigningCertificate == null) { throw new CertificateIssuerException("Cannot create certificate without signing certificate (null)."); } (AsymmetricCipherKeyPair caKeyPair, X509Name issuer) = GetSigningKeyPair(definition.SigningCertificate); var publicKeyForNewCert = PublicKeyFactory.CreateKey(definition.PublicKey); var certGen = new X509V3CertificateGenerator(); certGen.SetSerialNumber(serialNumber); certGen.SetIssuerDN(issuer); certGen.SetSubjectDN(definition.Subject); certGen.SetPublicKey(publicKeyForNewCert); var now = DateTime.Now; certGen.SetNotBefore(now.Subtract(new TimeSpan(0, 0, 10, 0))); // start 10 min before now // add max 2 weeks from now but not more then L2 expiration date var certExpirationDate = now.Add(definition.ExpireIn); var signingCertificateNotAfter = definition.SigningCertificate.NotAfter; if (signingCertificateNotAfter < now) { throw new CertificateIssuerException( "Cannot create derived certificate because signing certificate already expired. Signing certificate subject name: " + definition.SigningCertificate?.SubjectName.Name); } if (certExpirationDate > signingCertificateNotAfter) { certExpirationDate = signingCertificateNotAfter; } certGen.SetNotAfter(certExpirationDate); // certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false)); AddExtensionSubjectKeyIdentifier(certGen, publicKeyForNewCert); AddExtensionAuthorityKeyIdentifier(certGen, caKeyPair); AddExtensionSubjectAltNames(certGen, definition.SubjectAltNames); // var s = @"file:////my-CA.com/CertEnroll/my-CA.com_my-Dev%20L2%20CA.crt"; // AddExtensionAuthorityInfo(certGen, s); // string certificateTemplateExtension = "IPSECIntermediateOffline"; // AddExtensionCertificateTemplateName(certGen, certificateTemplateExtension); // var crl = @"file:////my-CA.com/CertEnroll/my-Dev%20L2%20CA.crl"; // AddExtensionCrlDistributionPoints(certGen, crl); // other supported algorithms: /* SHA1withECDSA * SHA224withECDSA * SHA256withECDSA * SHA384withECDSA * SHA512withECDSA * NONEwithECDSA */ const string algorithm = "SHA256WITHECDSA"; // This is the most interesting part where we use our custom signature factory that utilizes // the custom private key PksEcPrivateKey ISignatureFactory signatureFactory = new PksAsn1SignatureFactory(algorithm, caKeyPair.Private, new SecureRandom(randomGenerator)); X509Certificate cert = certGen.Generate(signatureFactory); return(cert); }