X.509 certificate generation with RSA or ECDSA signing in JavaScript
| Method |
RSA: ECC: |
|---|---|
| Private Key (scroll of more details) | |
| Public Key (scroll of more details) | |
| X509 |
Theory
X.509 was initially defined by the ISO in 1988 - as part of their OSI (Open System Integration) approach. The focus of X.509 is to bind a given identity to a public key and thus prove digital signatures. Their basic structure is based on Abstract Syntax Notation One (ASN.1). To advance their adoption, the X.509 format was further standardized on the Internet with RFC 3279 [1]:

We can add many elements to a digital certificate, including:
Version Number Serial Number Signature Algorithm ID Issuer Name Validity Not Before Validity Not After Subject name Public Key Algorithm Subject Public Key Certificate Signature Algorithm Certificate Signature
These elements can be matched to the requirement, such as for the subject and the issuer's common name. An important element is a date that the certificate is valid from (Validity Not Before) and to (Validity Not After). A certificate which has a validity date not after that is before the current date is likely to be marked as untrusted.
If we look at a certificate, we can see some of these elements, including the subject and issuer name. This format includes CN (Common Name), O (Organisation) and C (Country):
site_url='https://example.com'
curl -v --insecure $site_url 2>&1 | awk '/^* subject:/ {print $0}'
> * subject: C=US; ST=California; L=Los Angeles; O=Internet?Corporation?for?Assigned?Names?and?Numbers; CN=www.example.org
site_url='example.com'
echo | openssl s_client -servername "$site_url" -connect "$site_url":443 2>/dev/null | openssl x509 -noout -subject
> subject=C = US, ST = California, L = Los Angeles, O = Internet\C2\A0Corporation\C2\A0for\C2\A0Assigned\C2\A0Names\C2\A0and\C2\A0Numbers, CN = www.example.org
echo | openssl s_client -servername "$site_url" -connect "$site_url":443 2>/dev/null | openssl x509 -noout -issuer -dates -pubkey
>
issuer=C = US, O = DigiCert Inc, CN = DigiCert Global G2 TLS RSA SHA256 2020 CA1
notBefore=Jan 30 00:00:00 2024 GMT
notAfter=Mar 1 23:59:59 2025 GMT
-----BEGIN PUBLIC KEY-----
MII...QAB
-----END PUBLIC KEY-----
View Certificate
we display in a PEM and in an ASN.1 format. With PEM we have a Base64 form - which is easy to port across systems. With ASN.1 we can see the details of the certificate contents. Sample for ECDSA is:
ECC Certificate [SHA256withECDSA]: (secp256r1) -----BEGIN CERTIFICATE----- MII... : ...5wDL -----END CERTIFICATE-----
# Step 1: Get the certificate in PEM format site_url='example.com' echo | openssl s_client -servername "$site_url" -connect "$site_url":443 2>/dev/null | openssl x509 -outform PEM -out cert.pem # Step 2: Convert the PEM certificate to DER format openssl x509 -in cert.pem -outform der -out cert.der # Step 3: Parse the DER certificate for ASN.1 structure openssl asn1parse -in cert.der -inform der -i rm -rf cert.der cert.pem
With ASN.1 we define an OID. In this case "1.2.840.10045.4.3.2" identifies ECDSA with SHA256 signing, and "2.5.4.3" identifies the common name of either the subject or the issuer. For an RSA signed certificate, a sample run gives [here]:
RSA Signed Certificate [SHA1withRSA]: (512 bits) -----BEGIN CERTIFICATE----- MII... : ...SA== -----END CERTIFICATE-----
References
[1] RFC 3279, Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile [here]
A list of object IDs:
Hashing: MD2 1.2.840.113549.2.2 MD5 1.2.840.113549.2.5 SHA-1 1.3.14.3.2.26 SHA-224 2.16.840.1.101.3.4.2.4 SHA-256 2.16.840.1.101.3.4.2.1 SHA-394 2.16.840.1.101.3.4.2.2 SHA-512 2.16.840.1.101.3.4.2.3 Public key: RSA Encryption 1.2.840.113549.1.1.1 DSA 1.2.840.10040.4.1 Diffie-Hellman (dhPublicNumber) 1.2.840.10046.2.1 ECC (ecPublicKey) 1.2.840.10045.2.1 md2WithRsaEncryption 1.2.840.113549.1.1.2 Signatures: md5WithRsaEncryption 1.2.840.113549.1.1.4 sha1WithRsaEncryption 1.2.840.113549.1.1.5 sha224WithRsaEncryption 1.2.840.113549.1.1.14 sha256WithRsaEncryption 1.2.840.113549.1.1.11 sha384WithRsaEncryption 1.2.840.113549.1.1.12 sha512WithRsaEncryption 1.2.840.113549.1.1.13 dsaWithSha1 1.2.840.10040.4.3 dsaWithSha224 2.16.840.1.101.3.4.3.1 dsaWithSha256 2.16.840.1.101.3.4.3.2 ecdsaWithSha1 1.2.840.10045.4.1 ecdsaWithSha224 1.2.840.10045.4.3.1 ecdsaWithSha256 1.2.840.10045.4.3.2 ecdsaWithSha384 1.2.840.10045.4.3.3 ecdsaWithSha512 1.2.840.10045.4.3.4 Password Base Encryption Algorithms: pbeWithMd2AndDesCbc 1.2.840.113549.1.5.1 pbeWithMd5AndDesCbc 1.2.840.113549.1.5.3 pbeWithSha1AndDesCbc 1.2.840.113549.1.5.10 pbeWithMd2AndRc2Cbc 1.2.840.113549.1.5.4 pbeWithMd5AndRc2Cbc 1.2.840.113549.1.5.6 pbeWithSha1AndRc2Cbc 1.2.840.113549.1.5.11 pbeWithSha1And40BitRc2Cbc 1.2.840.113549.1.12.1.6 pbeWithSha1And128BitRc2Cbc 1.2.840.113549.1.12.1.5 pbeWithSha1And40BitRc4 1.2.840.113549.1.12.1.2 pbeWithSha1And128BitRc4 1.2.840.113549.1.12.1.1 pbeWithSha1And3DesCbc 1.2.840.113549.1.12.1.3 Symmetric EncryptionAlg orithms: DES CBC 1.3.14.3.2.7 3DES CBC 1.2.840.113549.3.7 RC2 1.2.840.113549.3.2 ArcFour 1.2.840.113549.3.4 AES CBC 128 2.16.840.1.101.3.4.1.2 AES CBC 256 2.16.840.1.101.3.4.1.42x.500 Distinguished Name Attributes: name 2.5.4.41 surname 2.5.4.4 given name 2.5.4.42 initials 2.5.4.43 generation qualifier 2.5.4.44 common name 2.5.4.3 locality name 2.5.4.7 state or province name 2.5.4.8 organization name 2.5.4.10 organizational unit name 2.5.4.11 title 2.5.4.12 dnQualifier 2.5.4.46 country name 2.5.4.6 email address 1.2.840.113549.1.9.1 domain component 0.9.2342.19200300.100.1.25 street address 2.5.4.9 postal code 2.5.4.17 mail 0.9.2342.19200300.100.1.3 serial number 2.5.4.5 ECC names: secp192r1 1.2.840.10045.3.1.1 secp224r1 1.3.132.0.33 secp256r1 1.2.840.10045.3.1.7 secp384r1 1.3.132.0.34 secp521r1 1.3.132.0.35 brainpoolP160r1 1.3.36.3.3.2.8.1.1.1 brainpoolP192r1 1.3.36.3.3.2.8.1.1.3 brainpoolP224r1 1.3.36.3.3.2.8.1.1.5 brainpoolP256r1 1.3.36.3.3.2.8.1.1.7 brainpoolP320r1 1.3.36.3.3.2.8.1.1.9 brainpoolP384r1 1.3.36.3.3.2.8.1.1.11 brainpoolP512r1 1.3.36.3.3.2.8.1.1.13