Unwrapping Certificates

Certificates are an important part of modern digital infrastructure, but most of the time, we don’t really have to think about what they look like or how they work. Certificates and their role in digital security are neither as mystical or as complicated as they appear. In this post, we’ll be unwrapping the certificates used in Golioth’s device authentication mechanism, and take a look at what they really do.

What is a certificate, really?

Fundamentally, certificates are statements that have been verified by a trusted authority. The statements can generally be anything, like “Trond likes pancakes!” and a digital signature is attached to the certificate to prove that a certificate authority verified the statement. The signature is generated specifically for the statement, so if anyone changes the statement in any way, the signature will no longer match.

The chain of trust

The certificate authority is someone we already trust. At some point, whoever owns the certificate went to the authority with their statement and had them verify and sign it.

By checking that the authority’s signature is valid, we know that we can trust the statement, because we trust the authority and their judgement. This is referred to as a chain of trust; We trust the authority that verified this statement, therefore we trust that the statement is true.

The trusted authority can also extend the chain of trust by appointing “deputies” that will verify statements on their behalf. The deputies have their own certificates (issued by the trusted authority), that proves that they are to be trusted as well. We refer to the original authority’s certificate as a root certificate, and the deputy’s certificate as an intermediate certificate.

The deputy can also go and create deputies of their own (infinitely, in theory), but they’ll have to provide a chain of certificates, going all the way back up to the root (or at least up to an intermediate certificate that we trust) as proof of their trustworthiness. If anyone in this chain of trust has had their certificate revoked, the entire chain is broken (but not chains built from other intermediate CAs).

Public key certificates

The most common type of certificate in digital security is a public key certificate. Public key certificates contain a public key and a unique identifier for the owner of that public key. If we trust the authority that signed a public key certificate, we can trust that the public key belongs to the entity with that ID.

In addition to the ID and public key, public key certificates will contain some extra information that helps us trust them:

  • A unique serial number for the certificate
  • A time range for when the certificate is valid
  • A list of operations the certificate can be used for
  • The name of the certificate authority that issued the certificate

Golioth uses public key certificates to prove that a device with a specific ID is the owner of a specific public key. Every device that has been provisioned with a certificate will present its certificate to the Golioth servers when connecting. The certificate must be signed by a certificate authority that you registered in the Golioth console in advance, so that the server knows that it can trust the contents of the certificate.

Certificate Signing Requests

In order to get a certificate authority to issue a certificate for us, we need to make a certificate signing request. A certificate signing request looks a lot like a certificate: It contains a public key, a unique ID for the owner and a signature, but there are some important distinctions in how they work. When we want a certificate authority to issue a certificate for us, we need to prove two things

  • This is actually our public key
  • We are, in fact, who we say we are.

We can prove that we own the public key by signing the request with our own key pair. If we’re able to sign the request so that it can be verified with the embedded public key, we must really be the owner of the corresponding private key as well. Certificate signing is a cryptographic topic that is deep and probably unnecessary for this conversation, but see [1] for more resources.

The second part – proving that we are actually who we say we are, is a little trickier. There are several ways to solve this, but they’re usually based on some sort of external verification method. In an IoT setting, the easiest way to ensure that we’re really communicating with the device, and not an impostor, is usually through physical access. For example, we can physically connect a cable to our device while it’s still in the factory, and have it issue a certificate signing request to us directly. Because it’s happening in a safe environment over a connection that can’t realistically be spoofed, we can trust that the device really is who it says it is, and we can safely issue a certificate for it.

Authenticating with certificates

Although the certificate contains an ID, it doesn’t actually prove that the holder of the certificate is whoever the certificate says it is. In fact, we’re all giving away our certificates to anyone who asks, and nothing is stopping them from passing it along to others, so how can we know that the holder of the certificate is the owner?

To solve this, we need to include a challenge as part of the certificate exchange, where only the true owner of the certificate can give the right answer.

This is where the public key comes in: When public key cryptography is used to create digital signatures, anyone with the public key can verify the signature, but only someone with the corresponding private key can generate them! So if the holder of the certificate can generate a signature that we can verify with the public key, we can prove that they really are who the certificate says they are.

Therefore, when a device connects to Golioth’s servers, they’ll be asked to send over their certificate, but they’ll also be asked to generate a unique digital signature for all the data exchanged so far in this session. If the certificate is legitimate, and the digital signature can be verified with the public key embedded in it, we know that the device is the true owner of the certificate. The device is authenticated, and we can establish a shared session key to start sending data.

💡 This diagram is a simplification of the DTLS 1.3 handshake. In a real handshake, the Hello messages also contain a temporary public key that is used to create a shared secret that the rest of the exchange is encrypted with. The device will also authenticate the Golioth servers the same way, using a certificate authority certificate embedded in its firmware. For a detailed walkthrough of the actual DTLS handshake, check out this guide.

Certificate format

If you follow Golioth’s guide for how to generate a test certificate, you’ll get a .pem file that looks a little something like this:

-----BEGIN CERTIFICATE-----
MIIBpzCCAU6gAwIBAgIQEBgj9TLbEHtKozGlmjuJVzAKBggqhkjOPQQDAjAtMQsw
CQYDVQQGEwJOTzEeMBwGA1UEAwwVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTI1
MDMxNDExMDQxMVoXDTI2MDMxNDExMDM1MVowNzELMAkGA1UEBhMCTk8xFTATBgNV
BAoTDHR1cnRsZS1yYWNlcjERMA8GA1UEAxMIZnJhbmtsaW4wWTATBgcqhkjOPQIB
BggqhkjOPQMBBwNCAATCR9XKSuimLhV5DownwVzN52R/lPrKWCOQbNcVLVWToM/3
C/0eFGU5CPwTx45IPW7JTriqnq+jHZR92WZnTPtwo0YwRDATBgNVHSUEDDAKBggr
BgEFBQcDAjAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHn4Hr/4r52jQREMAseo
9W0XA1XrMAoGCCqGSM49BAMCA0cAMEQCIEX92brnVn2/2vadThOP3n3EbqZ1qhyl
WRsMbiK9m0IVAiBBwKI6LGRI6FKXDWTCLj4KoWCktLF6U0G9fbTNgfQjTw==
-----END CERTIFICATE-----

I generated this certificate for a device named franklin in my turtle-racer project. The certificate was signed by a certificate authority named Certificate Authority, and expires on the 14th of March, 2026.

At first glance, this pem file is just an unintelligible blob of data surrounded by some sort of header and footer. Certificates, signatures and public keys always feel a bit like that, so it’s easy to just dismiss them as a magic blob and move on, but let’s dive a bit deeper:

The data blob in the middle is actually a base64-encoded structured binary object, so let’s start by stripping away the header and footer, and decode it:

$ sed '1,1d; $d' device.crt.pem  | base64 -d | xxd

And the result

00000000: 3082 01a7 3082 014e a003 0201 0202 1010  0...0..N........
00000010: 1823 f532 db10 7b4a a331 a59a 3b89 5730  .#.2..{J.1..;.W0
00000020: 0a06 082a 8648 ce3d 0403 0230 2d31 0b30  ...*.H.=...0-1.0
00000030: 0906 0355 0406 1302 4e4f 311e 301c 0603  ...U....NO1.0...
00000040: 5504 030c 1543 6572 7469 6669 6361 7465  U....Certificate
00000050: 2041 7574 686f 7269 7479 301e 170d 3235   Authority0...25
00000060: 3033 3134 3131 3034 3131 5a17 0d32 3630  0314110411Z..260
00000070: 3331 3431 3130 3335 315a 3037 310b 3009  314110351Z071.0.
00000080: 0603 5504 0613 024e 4f31 1530 1306 0355  ..U....NO1.0...U
00000090: 040a 130c 7475 7274 6c65 2d72 6163 6572  ....turtle-racer
000000a0: 3111 300f 0603 5504 0313 0866 7261 6e6b  1.0...U....frank
000000b0: 6c69 6e30 5930 1306 072a 8648 ce3d 0201  lin0Y0...*.H.=..
000000c0: 0608 2a86 48ce 3d03 0107 0342 0004 c247  ..*.H.=....B...G
000000d0: d5ca 4ae8 a62e 1579 0e8c 27c1 5ccd e764  ..J....y..'.\..d
000000e0: 7f94 faca 5823 906c d715 2d55 93a0 cff7  ....X#.l..-U....
000000f0: 0bfd 1e14 6539 08fc 13c7 8e48 3d6e c94e  ....e9.....H=n.N
00000100: b8aa 9eaf a31d 947d d966 674c fb70 a346  .......}.fgL.p.F
00000110: 3044 3013 0603 551d 2504 0c30 0a06 082b  0D0...U.%..0...+
00000120: 0601 0505 0703 0230 0e06 0355 1d0f 0101  .......0...U....
00000130: ff04 0403 0201 0630 1d06 0355 1d0e 0416  .......0...U....
00000140: 0414 79f8 1ebf f8af 9da3 4111 0c02 c7a8  ..y.......A.....
00000150: f56d 1703 55eb 300a 0608 2a86 48ce 3d04  .m..U.0...*.H.=.
00000160: 0302 0347 0030 4402 2045 fdd9 bae7 567d  ...G.0D. E....V}
00000170: bfda f69d 4e13 8fde 7dc4 6ea6 75aa 1ca5  ....N...}.n.u...
00000180: 591b 0c6e 22bd 9b42 1502 2041 c0a2 3a2c  Y..n"..B.. A..:,
00000190: 6448 e852 970d 64c2 2e3e 0aa1 60a4 b4b1  dH.R..d..>..`...
000001a0: 7a53 41bd 7db4 cd81 f423 4f              zSA.}....#O

This is still somewhat unintelligible, but there’s some text in there that we can recognize: both my project ID, device name and the name Certificate Authority appears in plaintext! But what’s all the stuff around it, and where is my public key?

ASN.1

The generated certificate, like most artifacts generated by OpenSSL is actually a structured binary object in ASN.1 notation. ASN.1 is not too different from CBOR, our favorite binary object representation here at Golioth. It lets us define nested objects, with arrays, integers, strings and other data types.

Although OpenSSL’s asn1decode utility can decode any ASN.1 encoded binary object for us, Lapo Luchini’s online ASN.1 decoder is both more powerful, and easier to understand. It presents a structured view of our certificate:

As we can see from this output, the certificate forms a sort of tree structure, and at the root of the tree is a sequence (or array, if you prefer) with three elements. The structure and order of the elements within the sequence is standardized by the ITU. Certificates in this format is referred to as an X.509 Certificate, and all have the same fields in the same order.

X.509 Certificates

X.509 Certificates refer to the owner of the certificate as the “subject”, and all contain the same information, in the same order:

  • Certificate
    • Version: v3 (actually encoded as 0x02, for added fun)
    • Sequence number: A unique sequence number for this certificate
    • Signature algorithm ID: The ID of the algorithm used to sign this certificate
    • Issuer name: A structured object with fields identifying the certificate authority that issued this certificate.
    • Validity period
      • Not before: The date and time the certificate is valid from
      • Not after: The date and time the certificate is valid to
    • Subject name: A structured object with fields uniquely identifying the certificate owner.
    • Subject public key info
      • Public key algorithm: The public key type
      • Subject public key: The actual public key of the owner
    • Extensions (optional): A list of optional extensions adding restrictions to the usage of the certificate, or helping identifying the owner of the certificate.
  • Certificate signature algorithm: The ID of the algorithm used to sign this certificate
  • Certificate signature: The raw signature for this certificate, generated by the certificate authority that issued the certificate.

If you squint hard enough, you can recognize this structure in the output from the online decoder:

You may notice some identifiers that appear to magically have very specific meanings here, like the signature algorithm identifier 1.2.840.10045.4.3.2. These identifiers are a special ASN.1 data type for official Object Identifiers (also standardized by the ITU). Each unique object identifer has a special meaning, which the ASN.1 decoder needs to recognize to be able to interpret. Luckily for us, Lapo’s decoder knows about all of these, and can tell us that 1.2.840.10045.4.3.2 is ecdsaWithSHA256 – an elliptic curve signature algorithm that uses SHA-256 to create a hash of the certificate.

Subject and Issuer Names

When creating certificates with OpenSSL, we have to specify a subject line to identify the content of the certificate, typically on a standardized text form. For example, when generating my certificate, I typed in C=NO, O=turtle-racer, CN=franklin:

  • My device’s country, C is Norway
  • My device’s organization, O is turtle-racer
  • My device’s common name, CN is franklin

This is a common shorthand for these names, but as we can see from the interpreted ASN.1 object they actually end up being encoded as structured objects as well:

SEQUENCE (3 elem)
  SET (1 elem)
    SEQUENCE (2 elem)
      OBJECT IDENTIFIER 2.5.4.6 countryName
      PrintableString NO
  SET (1 elem)
    SEQUENCE (2 elem)
      OBJECT IDENTIFIER 2.5.4.10 organizationName
      PrintableString turtle-racer
  SET (1 elem)
    SEQUENCE (2 elem)
      OBJECT IDENTIFIER 2.5.4.3 commonName
      PrintableString franklin

Other cryptographic objects

Although we’ve mainly focused on certificates in this post, there are more objects involved in the process, like public keys, private keys and certificate signing requests. Not only do they get passed around in the same .pem files as the certificates, they also follow the same ASN.1 notation! Although you shouldn’t ever give away your private keys to an online decoder tool, no matter how neat it is, you can try the ASN.1 parser on any of the other files you’ve made in your certificate generation process to see what’s in them. It also contains examples of common objects, including certificate signing requests and private keys.

In conclusion

Certificates are a powerful mechanism for safely authenticating IoT devices, and once we get past the urge to treat them as opaque binary blobs, we can see that they’re actually fairly simple objects.

Certificate based authentication remains the recommended way of authenticating your devices with Golioth, and hopefully this post helped demystify them a bit!

 

Other resources

  1. What is a digital signature (Wikipedia)

Post Comments

No comments yet! Start the discussion at forum.golioth.io

More from this author

Related posts

spot_img

Latest posts

A Device That Can’t Be Updated Is a Device That Can’t Be Trusted

Over-the-air updates are a crucial part of building and deploying secured devices, yet many product companies skip this step. This post outlines why it's difficult and how Golioth is making it easier.

Spring Cleaning with Golioth: Dust off your Zephyr skills in April 2025

Spring is a time of renewal, growth, and fresh starts—and your IoT projects deserve some spring cleaning, too! Dust off those ideas sitting idle, sharpen your embedded development toolkit, and join us for a free Zephyr RTOS Training on April 30th, 2025.

Use your J-Link Programmer as a Serial Port for your Device

If you're already using a J-Link programmer in your embedded development, you can use it to interface directly with the target device serial port over the J-Link USB connection. This is extremely handy, especially if your hardware design connects RX/TX pins to the programming header.

Want to stay up to date with the latest news?

Subscribe to our newsletter and get updates every 2 weeks. Follow the latest blogs and industry trends.