Hello world,

Today I’m continuing my certutil tips and tricks post series. In this post, I will show how cryptographic objects are stored in files and how certutil can convert between different presentation formats.

Binary formatting

In a nutshell, all cryptographic objects are stored in a binary stream form which is ready for transfer (transfer syntax, or raw syntax). However, transfer syntax is not suitable for other presentation forms, especially, display forms. For example, if we open binary certificate in notepad, we may see a mess like this:

image

We can see a lot of non-printable characters. This means that we cannot copy/paste its contents into a text-based messaging system (web page, email body, IM, etc.). The only thing we can do here is to attach the file. If messaging system doesn’t support file attachments, we are out of luck.

Fortunately, there are various kinds of binary serializers which can convert binary string into a series of printable characters and which can be converted back to binary stream afterwards. Most common binary serializers used in cryptography are hexadecimal encodings and PEM (Privacy Enhancement for Internet Electronic Mail).

Hexadecimal formatting

Hexadecimal presentation converts binary strings to a series of octets that use printable characters: A-F, a-f, 0-9. For example, most network traffic analyzers offer HEX-encoded packet presentation, also called a hex view:

 image

At a minimum, hexadecimal formatting consists of a series of octets:

30 82 06 91 30 82 05 79  a0 03 02 01 02 02 10 09
77 72 da 4a 53 ea db e8  6f e0 1a 4f 97 f9 0a 30
0d 06 09 2a 86 48 86 f7  0d 01 01 0b 05 00 30 4d
31 0b 30 09 06 03 55 04  06 13 02 55 53 31 15 30
13 06 03 55 04 0a 13 0c  44 69 67 69 43 65 72 74
20 49 6e 63 31 27 30 25  06 03 55 04 03 13 1e 44
69 67 69 43 65 72 74 20  53 48 41 32 20 53 65 63
75 72 65 20 53 65 72 76  65 72 20 43 41 30 1e 17

where each octet represents a single byte. Some tools may add address pane to help to find the index of a particular byte in a binary stream:

image

For example, we want to get the index of selected octet. The octet string is split into lines with 16 octets per line. Address on the left indicates the index of the first octet on this line. So we simply add octet’s position on a line to a line’s base address: 0x86=134. So we can say that selected octet is 134th byte in a binary stream. Address pane is optional and is ignored when converting hex string to binary string.

Additionally, hex viewers may offer another pane with ASCII representation of particular octet:

image

However, non-printable characters are converted to dot character. So, you can copy/paste hex dump of the certificate to a text file directly from wireshark or another hex viewer to a text file, email body, IM, etc.,

Despite the fact that hex is quite common, it is not supported by most cryptographic tools.

PEM formatting

PEM uses base64 encoding with optional header and footer that may give indication about embedded object. For example:

-----BEGIN CERTIFICATE-----
MIIGkTCCBXmgAwIBAgIQCXdy2kpT6tvob+AaT5f5CjANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMjE0MDAwMDAwWhcN
MjAwMzMxMTIwMDAwWjBRMQswCQYDVQQGEwJMVjENMAsGA1UEBxMEUmlnYTEYMBYG
A1UEChMPU3lzYWRtaW5zIExWIElLMRkwFwYDVQQDExB3d3cuc3lzYWRtaW5zLmx2
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr8582ezmfQEzpbcKeGIX
/dWyCJLlJzUZe2uXXp3IfggjLwYJaVrsqruhATnZvQdbuN7kBV3gVQB00y3ImWSz
Q7UdmQJb0bTXJH4sgegMjfGmqj6sPe9/m+jx1vQPniQhM+nWmimTh2n+jMV6cOYV
Z5qGouLH0wx+kO8SppVdV6FWIYsA44cPnFgnxGwvIwx51gMQP8nygHt9SXFKdk1v
<...>
-----END CERTIFICATE-----

Here is an excerpt of certificate in PEM format. First line is PEM header and last line is PEM footer. The data between header and footer is actual data. Header and footer are not involved in decoding process and simply ignored. More details about PEM headers are described in RFC 1421. PEM formatting is supported by most cryptographic tools natively.

Certutil and file formats

As it was mentioned, there are three major forms to represent cryptographic objects:

  1. binary string
  2. hexadecimal
  3. PEM

Certutil has three switches to convert the data between different formats. Let’s explore them!

Binary to PEM

certutil -encode converts binary file to PEM file:

PS C:\Certs> # check binary file by reading top 3 lines:
PS C:\Certs> gc .\www.bin.cer -TotalCount 3
0‚‘0‚y  wrЪJSкЫиoаO—щ
0
       *†H†ч
PS C:\Certs> # convert to base64 file
PS C:\Certs> certutil -encode www.bin.cer www.pem.cer
Input Length = 1685
Output Length = 2376
CertUtil: -encode command completed successfully.
PS C:\Certs> gc .\www.pem.cer -TotalCount 5
-----BEGIN CERTIFICATE-----
MIIGkTCCBXmgAwIBAgIQCXdy2kpT6tvob+AaT5f5CjANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMjE0MDAwMDAwWhcN
MjAwMzMxMTIwMDAwWjBRMQswCQYDVQQGEwJMVjENMAsGA1UEBxMEUmlnYTEYMBYG
PS C:\Certs>

 certutil -encode accepts two parameters: input file in binary encoding and result file in PEM format.

PEM to Binary

Opposite operation to decode PEM/Base64 to binary file is accomplished by calling certutil –decode switch:

C:\Certs> certutil -decode www.pem.cer www.bin2.cer
Input Length = 2376
Output Length = 1685
CertUtil: -decode command completed successfully.
C:\Certs> gc .\www.bin2.cer -TotalCount 5
0‚‘0‚y  wrЪJSкЫиoаO—щ
0
       *†H†ч
 0M10      UUS10U
DigiCert Inc1'0%UDigiCert SHA2 Secure Server CA0
C:\Certs>

Hex to Binary

Certutil can convert literally any hex-formatted file to its binary copy by converting each octet to corresponding byte value. Here are 4 examples of different hex formats which will result into the same binary file. This is done by using certutil –decodehex switch.

Example 1: only hex octets

C:\Certs> gc .\www.hexh.cer -TotalCount 5
30 82 06 91 30 82 05 79  a0 03 02 01 02 02 10 09
77 72 da 4a 53 ea db e8  6f e0 1a 4f 97 f9 0a 30
0d 06 09 2a 86 48 86 f7  0d 01 01 0b 05 00 30 4d
31 0b 30 09 06 03 55 04  06 13 02 55 53 31 15 30
13 06 03 55 04 0a 13 0c  44 69 67 69 43 65 72 74

C:\Certs> certutil -decodehex .\www.hexh.cer www.binh.cer
Input Length = 5264
Output Length = 1685
CertUtil: -decodehex command completed successfully.

C:\Certs>

Example 2: hex octets with address pane

C:\Certs> gc .\www.hexah.cer -TotalCount 5
0000    30 82 06 91 30 82 05 79  a0 03 02 01 02 02 10 09
0010    77 72 da 4a 53 ea db e8  6f e0 1a 4f 97 f9 0a 30
0020    0d 06 09 2a 86 48 86 f7  0d 01 01 0b 05 00 30 4d
0030    31 0b 30 09 06 03 55 04  06 13 02 55 53 31 15 30
0040    13 06 03 55 04 0a 13 0c  44 69 67 69 43 65 72 74

C:\Certs> certutil -decodehex .\www.hexah.cer www.binah.cer
Input Length = 6112
Output Length = 1685
CertUtil: -decodehex command completed successfully.
C:\Certs>

Example 3: hex octets with ASCII pane

C:\Certs> gc .\www.hexha.cer -TotalCount 5
30 82 06 91 30 82 05 79  a0 03 02 01 02 02 10 09   0...0..y........
77 72 da 4a 53 ea db e8  6f e0 1a 4f 97 f9 0a 30   wr.JS...o..O...0
0d 06 09 2a 86 48 86 f7  0d 01 01 0b 05 00 30 4d   ...*.H........0M
31 0b 30 09 06 03 55 04  06 13 02 55 53 31 15 30   1.0...U....US1.0
13 06 03 55 04 0a 13 0c  44 69 67 69 43 65 72 74   ...U....DigiCert

C:\Certs> certutil -decodehex .\www.hexha.cer www.binha.cer
Input Length = 7301
Output Length = 1685
CertUtil: -decodehex command completed successfully.
C:\Certs>

Example 4: hex octets with address and ASCII panes:

C:\Certs> gc .\www.hexaha.cer -TotalCount 5
0000    30 82 06 91 30 82 05 79  a0 03 02 01 02 02 10 09   0...0..y........
0010    77 72 da 4a 53 ea db e8  6f e0 1a 4f 97 f9 0a 30   wr.JS...o..O...0
0020    0d 06 09 2a 86 48 86 f7  0d 01 01 0b 05 00 30 4d   ...*.H........0M
0030    31 0b 30 09 06 03 55 04  06 13 02 55 53 31 15 30   1.0...U....US1.0
0040    13 06 03 55 04 0a 13 0c  44 69 67 69 43 65 72 74   ...U....DigiCert

C:\Certs> certutil -decodehex .\www.hexaha.cer www.binaha.cer
Input Length = 8149
Output Length = 1685
CertUtil: -decodehex command completed successfully.
C:\Certs>

As you can see, all four examples accept input files in different hex formatting and produce the same binary file:

C:\Certs> Get-FileHash *bin*.cer

Algorithm       Hash                                                                   Path
---------       ----                                                                   ----
SHA256          D4D973A6D7EC43D2DB790EE181324C4E44C161369135FCC4458F347791422510       C:\Certs\www.bin.cer
SHA256          D4D973A6D7EC43D2DB790EE181324C4E44C161369135FCC4458F347791422510       C:\Certs\www.bin2.cer
SHA256          D4D973A6D7EC43D2DB790EE181324C4E44C161369135FCC4458F347791422510       C:\Certs\www.binah.cer
SHA256          D4D973A6D7EC43D2DB790EE181324C4E44C161369135FCC4458F347791422510       C:\Certs\www.binaha.cer
SHA256          D4D973A6D7EC43D2DB790EE181324C4E44C161369135FCC4458F347791422510       C:\Certs\www.binh.cer
SHA256          D4D973A6D7EC43D2DB790EE181324C4E44C161369135FCC4458F347791422510       C:\Certs\www.binha.cer



C:\Certs>

All binary files hashes match, so we can be sure that they are the same!

Binary to Hex

Certutil is able to convert binary file to hex by using a certutil –encodehex switch. Again, different hex formatting options are supported.

Example 1: binary to raw hex

C:\Certs> certutil -encodehex .\www.bin.cer www.h.cer 8
Input Length = 1685
Output Length = 5266
CertUtil: -encodehex command completed successfully.

C:\Certs> gc www.h.cer -TotalCount 5
30 82 06 91 30 82 05 79  a0 03 02 01 02 02 10 09
77 72 da 4a 53 ea db e8  6f e0 1a 4f 97 f9 0a 30
0d 06 09 2a 86 48 86 f7  0d 01 01 0b 05 00 30 4d
31 0b 30 09 06 03 55 04  06 13 02 55 53 31 15 30
13 06 03 55 04 0a 13 0c  44 69 67 69 43 65 72 74

C:\Certs>

Example 2: binary to hex octets with address pane:

C:\Certs> certutil -f -encodehex .\www.bin.cer www.ah.cer 10
Input Length = 1685
Output Length = 5796
CertUtil: -encodehex command completed successfully.

C:\Certs> gc www.ah.cer -TotalCount 5
0000    30 82 06 91 30 82 05 79  a0 03 02 01 02 02 10 09
0010    77 72 da 4a 53 ea db e8  6f e0 1a 4f 97 f9 0a 30
0020    0d 06 09 2a 86 48 86 f7  0d 01 01 0b 05 00 30 4d
0030    31 0b 30 09 06 03 55 04  06 13 02 55 53 31 15 30
0040    13 06 03 55 04 0a 13 0c  44 69 67 69 43 65 72 74

C:\Certs>

Example 3: binary to hex octets with ASCII pane

C:\Certs> certutil -f -encodehex .\www.bin.cer www.ha.cer 5
Input Length = 1685
Output Length = 7303
CertUtil: -encodehex command completed successfully.

C:\Certs> gc www.ha.cer -TotalCount 5
30 82 06 91 30 82 05 79  a0 03 02 01 02 02 10 09   0...0..y........
77 72 da 4a 53 ea db e8  6f e0 1a 4f 97 f9 0a 30   wr.JS...o..O...0
0d 06 09 2a 86 48 86 f7  0d 01 01 0b 05 00 30 4d   ...*.H........0M
31 0b 30 09 06 03 55 04  06 13 02 55 53 31 15 30   1.0...U....US1.0
13 06 03 55 04 0a 13 0c  44 69 67 69 43 65 72 74   ...U....DigiCert

C:\Certs>

Example 4: binary to hex octets with address and ASCII pane

C:\Certs> certutil -f -encodehex .\www.bin.cer www.aha.cer 11
Input Length = 1685
Output Length = 7833
CertUtil: -encodehex command completed successfully.

C:\Certs> gc www.aha.cer -TotalCount 5
0000    30 82 06 91 30 82 05 79  a0 03 02 01 02 02 10 09   0...0..y........
0010    77 72 da 4a 53 ea db e8  6f e0 1a 4f 97 f9 0a 30   wr.JS...o..O...0
0020    0d 06 09 2a 86 48 86 f7  0d 01 01 0b 05 00 30 4d   ...*.H........0M
0030    31 0b 30 09 06 03 55 04  06 13 02 55 53 31 15 30   1.0...U....US1.0
0040    13 06 03 55 04 0a 13 0c  44 69 67 69 43 65 72 74   ...U....DigiCert

C:\Certs>

Bonus stuff

With certutil you can convert binary file to raw Base64 (without PEM header and footer), CRL PEM (Base64 with X.509 CRL header and footer) and PKCS#10 PEM (certificate signing request).

Example 1: binary to X.509 CRL PEM

C:\Certs> certutil -f -encodehex .\www.bin.cer www.crl-pem.cer 9
Input Length = 1685
Output Length = 2370
CertUtil: -encodehex command completed successfully.

C:\Certs> gc www.crl-pem.cer -TotalCount 5
-----BEGIN X509 CRL-----
MIIGkTCCBXmgAwIBAgIQCXdy2kpT6tvob+AaT5f5CjANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMjE0MDAwMDAwWhcN
MjAwMzMxMTIwMDAwWjBRMQswCQYDVQQGEwJMVjENMAsGA1UEBxMEUmlnYTEYMBYG

C:\Certs>

Example 2: binary to PKCS#10 PEM

C:\Certs> certutil -f -encodehex .\www.bin.cer www.pkcs10-pem.cer 3
Input Length = 1685
Output Length = 2400
CertUtil: -encodehex command completed successfully.

C:\Certs> gc www.pkcs10-pem.cer -TotalCount 5
-----BEGIN NEW CERTIFICATE REQUEST-----
MIIGkTCCBXmgAwIBAgIQCXdy2kpT6tvob+AaT5f5CjANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMjE0MDAwMDAwWhcN
MjAwMzMxMTIwMDAwWjBRMQswCQYDVQQGEwJMVjENMAsGA1UEBxMEUmlnYTEYMBYG

C:\Certs>

Example 3: binary to Base64 without PEM header and footer

C:\Certs> certutil -f -encodehex .\www.bin.cer www.base64.cer 1
Input Length = 1685
Output Length = 2320
CertUtil: -encodehex command completed successfully.

C:\Certs> gc www.base64.cer -TotalCount 5
MIIGkTCCBXmgAwIBAgIQCXdy2kpT6tvob+AaT5f5CjANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgxMjE0MDAwMDAwWhcN
MjAwMzMxMTIwMDAwWjBRMQswCQYDVQQGEwJMVjENMAsGA1UEBxMEUmlnYTEYMBYG
A1UEChMPU3lzYWRtaW5zIExWIElLMRkwFwYDVQQDExB3d3cuc3lzYWRtaW5zLmx2

C:\Certs>

End lines

As we learned today, Windows’ built-in certutil.exe tool is quite powerful when talking about different presentations of cryptographic objects. With just few lines you can convert binary data in different presentation formatting and even presentation format back to its binary equivalent.


Share this article:

Comments:

Roman Krylov
Roman Krylov 25.02.2019 12:00 (GMT+2) Certutil tips and tricks: working with X.509 file format

Thank you very much, for that material.

Daniel Yehezkel
Daniel Yehezkel 08.04.2019 18:17 (GMT+2) Certutil tips and tricks: working with X.509 file format

Thanks you

I enjoy reading your stuff


Post your comment:

Please, solve this little equation and enter result below. Captcha