Digital Certificates and PKI in Cybersecurity

July 30, 2022 (2y ago)

Cybersecurity Public Key

What is one of the most important parts of cybersecurity that not many people understand? Well, I think it has something to do with digital certificates and how they work with PKI (Public Key Infrastructure). Ask a person who works in cybersecurity how digital certificates are made and how they are used, and they might not be able to give you a full answer. But overall, they have a trusted public key of an entity that has been verified by another generally trusted entity.

Digital Certificates

If Zeynep wants to show Tom that she is who she says she is, she signs a message with her private key. Tom can then use her public key to prove that the message was signed by her. For this, we need Sadettin to sign a digital certificate with Tom’s public key, and he will then use his private key to do this. Tom then uses Sadettin's public key to check the signature on this certificate. Tom can trust the public key on the certificate if he believes Sadettin has checked Zeynep's public key. Then, as a root certificate, Sadettin's public key can be put on Tom's computer. If Tom finds out that Sadettin's private key has been stolen, he can stop trusting it.

But we have a lot of different kinds of devices and operating systems. So, how do we make digital certificates that can be moved from one system to another? Well, the magic of this is described in X.509, which was first described by the ISO in 1988 as part of their OSI (Open System Integration) approach. The main goal of X.509 is to link an identity to a public key so that digital signatures can be proven. Abstract Syntax Notation One is the basis for how they are put together (ASN.1). RFC 3279 [1] further standardised the X.509 format on the Internet, making it easier for people to use.

Public Key Infrastructure

RSA and ECDSA signatures are the two main ways that digital signatures are made. We also say what method of hashing is used, like SHA1 or SHA256. SHA256 is better for hashing because it is safer. DSA, which uses discrete log methods, and Ed25519 are two other ways to sign something (which uses Curve 25519 for digital signing).

What does a digital certificate contain?

A digital certificate can have many things added to it, such as:

  • Serial Number
  • Version 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 need, like for the subject and the issuer's common name. The date the certificate is valid from (Validity Not Before) and until is an important part (Validity Not After). A certificate whose expiration date is not later than the current date is likely to be marked as not trustworthy.

If we look at a Google.com certificate, we can see some of these things, like the subject and the name of the company that issued the certificate. This format has CN (Common Name), O (Organisation), and C (Country):

google digital certificate

X.509 Implementation Using JavaScript

<script src="https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/10.5.26/jsrsasign-all-min.js"></script>
<script>
    function gorsa(size) {
        var kp = KEYUTIL.generateKeypair("RSA", size);

        var priv = KEYUTIL.getPEM(kp.prvKeyObj, "PKCS8PRV");
        var privhex = pemtohex(priv);
        var privasn1 = ASN1HEX.dump(pemtohex(priv));
        document.getElementById("privatekey").innerHTML = priv;
        document.getElementById("privatekey").innerHTML += "\n\nHex:\n" + privhex;
        document.getElementById("privatekey").innerHTML += "\n\nASN1:\n" + privasn1;
        pub = KEYUTIL.getPEM(kp.pubKeyObj, "PKCS8PUB");
        var pubhex = pemtohex(pub);
        var pubasn1 = ASN1HEX.dump(pemtohex(pub));
        document.getElementById("publickey").innerHTML = pub;
        document.getElementById("publickey").innerHTML += "\n\nHex:\n" + pubhex;
        document.getElementById("publickey").innerHTML += "\n\nASN1:\n" + pubasn1;

        var x = new KJUR.asn1.x509.Certificate({
            version: 3,
            serial: { int: 4 },
            issuer: { str: "/CN=XahidEx" },
            notbefore: "151231235959Z",
            notafter: "251231235959Z",
            subject: { str: "/CN=Web server" },
            sbjpubkey: kp.pubKeyObj,
            ext: [
                { extname: "basicConstraints", cA: false },
                { extname: "keyUsage", critical: true, names: ["digitalSignature"] },
                {
                    extname: "cRLDistributionPoints",
                    array: [{ fulluri: 'http://tom.xahidex.com/' }]
                }
            ],
            sigalg: "SHA1withRSA",
            cakey: kp.prvKeyObj
        });

        document.getElementById("X509").innerHTML = "RSA Signed Certificate [SHA1withRSA]: (" +size+" bits)\n" +x.getPEM();
        var certasn1 = ASN1HEX.dump(pemtohex(x.getPEM()));
        document.getElementById("X509").innerHTML += "\nASN.1:\n" + certasn1;
        

    }

    function goecc(name) {

        var kp = KEYUTIL.generateKeypair("EC", name);

        var priv = KEYUTIL.getPEM(kp.prvKeyObj, "PKCS8PRV");
        var privhex = pemtohex(priv);
        var privasn1 = ASN1HEX.dump(pemtohex(priv));
        document.getElementById("privatekey").innerHTML = priv;
        document.getElementById("privatekey").innerHTML += "\n\nHex:\n" + privhex;
        document.getElementById("privatekey").innerHTML += "\n\nASN1:\n" + privasn1;
        pub = KEYUTIL.getPEM(kp.pubKeyObj, "PKCS8PUB");
        var pubhex = pemtohex(pub);
        var pubasn1 = ASN1HEX.dump(pemtohex(pub));
        document.getElementById("publickey").innerHTML = pub;
        document.getElementById("publickey").innerHTML += "\n\nHex:\n" + pubhex;
        document.getElementById("publickey").innerHTML += "\n\nASN1:\n" + pubasn1;

        var x = new KJUR.asn1.x509.Certificate({
            version: 3,
            serial: { int: 4 },
            issuer: { str: "/CN=XahidEx" },
            notbefore: "151231235959Z",
            notafter: "251231235959Z",
            subject: { str: "/CN=Web server" },
            sbjpubkey: kp.pubKeyObj, 
            ext: [
                { extname: "basicConstraints", cA: false },
                { extname: "keyUsage", critical: true, names: ["digitalSignature"] },
                {
                    extname: "cRLDistributionPoints",
                    array: [{ fulluri: 'http://tom.xahidex.com/' }]
                }
            ],
            sigalg: "SHA256withECDSA",
            cakey: kp.prvKeyObj 
        });

        document.getElementById("X509").innerHTML = "ECC Certificate [SHA256withECDSA]: ("+name+")\n" + x.getPEM();
        var certasn1 = ASN1HEX.dump(pemtohex(x.getPEM()));
        document.getElementById("X509").innerHTML += "\nASN.1:\n" + certasn1;
     

    }</script>

Html is here

<table width="100%">
        <tr>
            <th valign="top">Method</th>
            <td style="text-align:left">

                <p>
                    RSA: <input type="button" class="btn btn-medium btn-success" onclick="gorsa(512)" value="Generate RSA 512"><input type="button" class="btn btn-medium btn-success" onclick="gorsa(1024)" value="Generate RSA 1024">

                </p>

                <p>
                    ECC: <input type="button" class="btn btn-medium btn-warning" onclick="goecc('secp256r1')" value="Secp256r1 (P-256)">
                    <input type="button" class="btn btn-medium btn-warning" onclick="goecc('secp256k1')" value="Secp256k1 (Ethereum)">

                    <input type="button" class="btn btn-medium btn-warning" onclick="goecc('secp384r1')" value="secp384r1">

                </p>

            </td>
        </tr>

        <tr>
            <th valign="top" width="15%">Private Key (scroll of more details)</th>
            <td>

                <textarea cols="20" id="privatekey" name="privatekey" rows="4" style="width:100%"></textarea>

            </td>
        </tr>
        <tr>
            <th valign="top">Public Key  (scroll of more details)</th>
            <td>

                <textarea cols="20" id="publickey" name="publickey" rows="4" style="width:100%"></textarea>

            </td>
        </tr>

        <tr>
            <th valign="top">X509</th>
            <td>

                <textarea cols="20" id="X509" name="X509" rows="20" style="width:100%"></textarea>

            </td>
        </tr>

    </table>

In this instance, we display in both the PEM and ASN.1 formats. With PEM, we have a Base64 format, which is simple to transfer between systems. With ASN.1, we can view the certificate's contents in their entirety. A sample run for ECDSA signing is

RSA Signed Certificate [SHA1withRSA]: (512 bits)
-----BEGIN CERTIFICATE-----
MIIBazCCARWgAwIBAgIBBDANBgkqhkiG9w0BAQUFADAYMRYwFAYDVQQDDA1BU2Vj
dXJpdHlzaXRlMB4XDTE1MTIzMTIzNTk1OVoXDTI1MTIzMTIzNTk1OVowFTETMBEG
A1UEAwwKV2ViIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCoRi3EtXPk
t/51SpZYa0WMa+rstDfM605BzNdRajziznusrRyxjyEQ0CMqE/+vaBy50ZkAAyKv
Q4ti6w02Y/j7AgMBAAGjTTBLMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeAMC4G
A1UdHwQnMCUwI6AhoB+GHWh0dHA6Ly9ib2IuYXNlY3VyaXR5c2l0ZS5jb20vMA0G
CSqGSIb3DQEBBQUAA0EAmvSwggR+V23TmFZ+Tf0WwzxjualDv6UPEkFx01H5oWzA
pXn7cOzyGRzcgPQjE3+2KLcTTU5Fo0dRoU5hujt3SA==
-----END CERTIFICATE-----
ASN.1:
SEQUENCE
  SEQUENCE
    [0]
      INTEGER 02
    INTEGER 04
    SEQUENCE
      ObjectIdentifier SHA1withRSA (1 2 840 113549 1 1 5)
      NULL
    SEQUENCE
      SET
        SEQUENCE
          ObjectIdentifier commonName (2 5 4 3)
          UTF8String 'XahidEx'
    SEQUENCE
      UTCTime 151231235959Z
      UTCTime 251231235959Z
    SEQUENCE
      SET
        SEQUENCE
          ObjectIdentifier commonName (2 5 4 3)
          UTF8String 'Web server'
    SEQUENCE
      SEQUENCE
        ObjectIdentifier rsaEncryption (1 2 840 113549 1 1 1)
        NULL
      BITSTRING, encapsulates
        SEQUENCE
          INTEGER 00a8462dc4b573e4b7fe754a96586b45..(total 65bytes)..b9d199000322af438b62eb0d3663f8fb
          INTEGER 010001
    [3]
      SEQUENCE
        SEQUENCE
          ObjectIdentifier basicConstraints (2 5 29 19)
          OCTETSTRING, encapsulates
            SEQUENCE {}
        SEQUENCE
          ObjectIdentifier keyUsage (2 5 29 15)
          BOOLEAN TRUE
          OCTETSTRING, encapsulates
            BITSTRING 0780
        SEQUENCE
          ObjectIdentifier cRLDistributionPoints (2 5 29 31)
          OCTETSTRING, encapsulates
            SEQUENCE
              SEQUENCE
                [0]
                  [0]
                    [6] http://tom.xahidex.com/
  SEQUENCE
    ObjectIdentifier SHA1withRSA (1 2 840 113549 1 1 5)
    NULL
  BITSTRING 009af4b082047e576dd398567e4dfd16..(total 65bytes)..28b7134d4e45a34751a14e61ba3b7748

Conclusions

I repeat. Digital certificates are probably one of the best ways to keep your information safe on the Internet because they define the trust infrastructure that is at its core. But they are also one of the most difficult to understand.