asp.net-core-webapibouncycastleasn.1asn1crypto

X.509 Certificate Generation with Ed25519 in ASP.NET: parameters ANY NULL Issue


I’m working on an ASP.NET Core Web API where one of the functionalities involves generating self-signed X.509 certificates. For this, I'm using the BouncyCastle library and the Ed25519 algorithm for key generation and signing.

The API is intended to create certificates dynamically, which are then used for secure communications. Everything works as expected during certificate generation, and no errors are thrown. However, when I analyze the generated certificate using an ASN.1 decoder, I notice an issue: the parameters ANY NULL field is included in the AlgorithmIdentifier section of the signature.

This is problematic because, according to the specifications for Ed25519 in X.509 (RFC 8410), the parameters field should be omitted for Ed25519. Here’s the problematic portion of the ASN.1 output:

signature AlgorithmIdentifier SEQUENCE (2 elem)
algorithm OBJECT IDENTIFIER 1.3.101.112 curveEd25519 (EdDSA 25519 signature algorithm)
parameters ANY NULL

The parameters field being set to NULL is not compliant with the standard for Ed25519 certificates, and this could lead to compatibility issues when the certificate is used in certain contexts or systems.

private X509Certificate CreateSelfSignedCertificate(X509Name subjectName, Pkcs10CertificationRequest csr, Ed25519PrivateKeyParameters privateKey, DateTime notBefore, DateTime notAfter)
{
    var certGen = new X509V3CertificateGenerator();

    var serialNumber = new BigInteger("2651512");
    certGen.SetSerialNumber(serialNumber);

    certGen.SetIssuerDN(subjectName);
    certGen.SetSubjectDN(subjectName);
    certGen.SetNotBefore(notBefore);
    certGen.SetNotAfter(notAfter);
    certGen.SetPublicKey(csr.GetPublicKey());

    certGen.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(csr.GetPublicKey()));
    var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(csr.GetPublicKey());

    certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, authorityKeyIdentifier);
    certGen.AddExtension(X509Extensions.BasicConstraints, false, CreateCustomExtensionValueRoot());

    var signatureFactory = new Asn1SignatureFactory(EdECObjectIdentifiers.id_Ed25519.Id, privateKey);

    return certGen.Generate(signatureFactory);
}

The certificate seems to be generated successfully, but the ASN.1 analysis of the AlgorithmIdentifier indicates the inclusion of the parameters field with a value of NULL. This does not conform to the Ed25519 algorithm specification, where the parameters field must be omitted entirely.Does anyone know how to solve this problem?


Solution

  • I believe this was fixed in the BouncyCastle.Cryptography NuGet package as of version 2.3.0.

    If stuck with an earlier version, you could provide your own implementation of ISignatureFactory:

    public class Ed25519SignatureFactory : ISignatureFactory
    {
        public Ed25519PrivateKeyParameters PrivateKey { get; init; }
    
        public object AlgorithmDetails => new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519);
    
        public IStreamCalculator<IBlockResult> CreateCalculator()
        {
            ISigner signer = SignerUtilities.InitSigner(EdECObjectIdentifiers.id_Ed25519, forSigning: true, PrivateKey,
                random: null);
            return new DefaultSignatureCalculator(signer);
        }
    }
    

    and use that instead:

    var signatureFactory = new Ed25519SignatureFactory { PrivateKey = privateKey };