Verifying digital signatures

9 minute read

Never install or use software without first verifying its digital signature.

1. Introduction

The verification of digital signatures ensures that a message wasn’t altered and that the sender is the one who ‘signed’ the message, the owner of the key pair.

Digital signatures use asymmetric cryptography: the signing process uses the private key and the verification process uses the public key from the same key pair.

If a message (or a file in any other format) has been modified in its origin or while in transit, the hashes will be different, and in this case (if the hacker published new hashes for the message), the hashes won’t have a valid digital signature.

In other words: If the hacker modifies the executable, its hash will be different from the hash in the manifest; if they are equal (in case the hacker also modified the manifest, because both are stored in Github), the digital signature of the manifest will be invalid because the manifest was signed with Decred developers’ private key, inaccessible to the hacker. The hacker would have to change the public key in MIT servers, where Decred developers’ public key is stored, and also the Github webpage with the instructions to import the correct public key (because the ID will change if the hacker decides to use his own key). Even going through all this trouble, it would work only for those who import the public key after the hacker replaces it with his own.

Just like the seed of the wallet (mnemonic for the private key) must be kept secret, the private key of the pair must also be kept in a secure location. The public key (just like Decred public addresses, derived from the master public key) may be divulged without compromising the private key.

Figure 1 — The process — Rebuilt from Microsoft Windows Dev Center, Digital Signatures
Figure 1 — The process — Rebuilt from Microsoft Windows Dev Center, Digital Signatures

2. How does digital signature work

2.1. Hash

It is the output of a mathematical function that always returns a fixed length sequence regardless of the size of the input.

Figure 2 - Cryptographic hash functions - Rebuilt from Wikipedia
Figure 2 - Cryptographic hash functions - Rebuilt from Wikipedia

Any modification in the input - the text, the length or the order of the characters - will produce a totally different output from what was expected.

2.2. Signature process

a) The hash of the message or file is generated (in this case stored in the file manifest-decrediton-$VERSION.txt)

b) The hash (in this case, the manifest) is signed (encrypted) with the private key (in this case the signed hash is stored in the file manifest-decrediton-$VERSION.txt.asc)

Decrediton sigital signature and verification process schematics

Figure 3 - Signing process (black arrows), verification process (white arrows)
Figure 3 - Signing process (black arrows), verification process (white arrows)

2.3. Verification process

a) The hash of the message or downloaded file is generated.

b) The signed hash (encrypted) is decrypted using the sender’s public key and the original hash is obtained. If both hashes are equal, the message wasn’t altered and the sender is who we think he is, because this public key could not decrypt a hash encrypted with a private key from another pair. In asymmetric cryptography both keys from the same pair are used. The process started with one key is finished with the other one.

3. What are the risks?

The risks change accordingly to the software that may have been compromised. In the case of cryptocurrency wallets it is possible that the attacker copy the seed or the private key to transfer all the resources to other addresses. In other cases the threats include information leakage, unauthorized access to user-stored information and even remote access or privilege escalation depending on the malicious code inserted into the original software.

4. File verification

Never install or use software without first verifying its digital signature.

This recommendation is related to software in general. Even the most simple software, like calculators or text editors, that don’t need administrative credentials to install or execute, may contain malicious code that exploits a vulnerability in the operating system or kernel. The broader recommendation should be: do not install untrusted software in your device, and when you decide to install something, download it from official sources and verify its digital signature, if possible.

This section describes the steps to download and verify Decrediton. These steps may be used to verify any other downloaded software from the Internet. The user will have to import the developers’ public key (hopefully all this information will be displayed in the website). Usually public keys are imported once, then again only if the key pair is revoked or replaced.

Learn more:

4.1. Mac

a) Go to https://github.com/decred/decred-binaries/releases/

b) Download to the same directory the files decrediton-$VERSION.dmg, manifest-decrediton-$VERSION.txt and manifest-decrediton-$VERSION.txt.asc

c) In case the key hasn’t already been imported (error: ‘gpg: Can’t check signature: No public key’): import the developer’s public key (GPG will try to connect to the Internet using port TCP/11371):

$ gpg --keyserver pgp.mit.edu --recv-keys 0x518A031D

d) Make sure the correct key was imported:

gpg: key 6DF634AA7608AF04: public key "Decred Release <release@decred.org>" imported

e) Verify the digital signature:

$ gpg --verify manifest-decrediton-$VERSION.txt.asc

gpg: assuming signed data in 'manifest-decrediton-v1.1.3.txt'
gpg: Signature made Thu Dec 21 17:15:58 2017 WET
gpg:                using RSA key 6D897EDF518A031D
gpg: Good signature from "Decred Release <release@decred.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: FD13 B683 5E24 8FAF 4BD1  838D 6DF6 34AA 7608 AF04
     Subkey fingerprint: F516 ADB7 A069 852C 7C28  A02D 6D89 7EDF 518A 031D

f) Look in the gpg output for: “using RSA key 6D897EDF518A031D” (only when verifying for the first time after importing the key). Notice that the second half of the RSA key, shown in the third line above, is shown in step c) and also the text ‘Good signature from “Decred Release”’

g) To generate the hash and manually compare it with the hashes inside manifest-decrediton-$VERSION.txt:

$ shasum -a 256 decrediton-$VERSION.dmg
$ cat manifest-decrediton-$VERSION.txt

h) Mount the DMG image and copy the new Decrediton app to the Applications folder.

Reference: https://docs.decred.org/advanced/verifying-binaries/

Obs.: If you don’t have gpg, go to https://gpgtools.org/

Web of Trust

The warning shown in step e) above with a message about the key not being certified with a trusted signature is related to PGP Web of Trust. In a decentralized model there is no central authority like the Certification Authority in PKI that can tell if a key belongs to one specific user (identity validation). So the web of trust works by verifying if a key is ‘signed’ by other key (user) trusted by the system, creating a web of trust. Considering I don’t trust any key that could have signed Decred developers’ public key, this warning was already expected.

4.2. Debian

a) Go to https://github.com/decred/decred-binaries/releases/

b) Download to the same directory the files decrediton-$VERSION.deb, manifest-decrediton-$VERSION.txt and manifest-decrediton-$VERSION.txt.asc

c) In case the key hasn’t already been imported (error: ‘gpg: Can’t check signature: No public key’): import the developer’s public key (GPG will try to connect to the Internet using port TCP/11371):

$ gpg --keyserver pgp.mit.edu --recv-keys 0x518A031D

In case of error ‘gpg: keyserver receive failed: No dirmngr’:

$ sudo apt-get install dirmngr

d) Make sure the correct key was imported:

gpg: key 6DF634AA7608AF04: public key "Decred Release <release@decred.org>" imported

e) Verify the digital signature:

$ gpg --verify manifest-decrediton-$VERSION.txt.asc

gpg: assuming signed data in 'manifest-decrediton-v1.1.3.txt'
gpg: Signature made Thu Dec 21 17:15:58 2017 WET
gpg:                using RSA key 6D897EDF518A031D
gpg: Good signature from "Decred Release <release@decred.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: FD13 B683 5E24 8FAF 4BD1  838D 6DF6 34AA 7608 AF04
     Subkey fingerprint: F516 ADB7 A069 852C 7C28  A02D 6D89 7EDF 518A 031D

f) Look in the gpg output for: “using RSA key 6D897EDF518A031D” (only when verifying for the first time after importing the key). Notice that the second half of the RSA key, shown in the third line above, is shown in step c) and also the text ‘Good signature from “Decred Release”’

g) To generate the hash and manually compare it with the hashes inside manifest-decrediton-$VERSION.txt:

$ sha256sum decrediton_$VERSION.deb
$ cat manifest-decrediton-$VERSION.txt

h) Install with command:

$ dpkg -i decrediton-$VERSION.deb

Warning in GPG output: Read more about Web of Trust in section 4.1.

Reference: https://docs.decred.org/advanced/verifying-binaries/

Obs.: If you don’t have gpg, go to https://gpgtools.org/

4.3. Other Linux flavors (and also on Debian)

a) Go to https://github.com/decred/decred-binaries/releases/

b) Download to the same directory the files decrediton-$VERSION.tar.gz, manifest-decrediton-$VERSION.txt and manifest-decrediton-$VERSION.txt.asc

c) In case the key hasn’t already been imported (error: ‘gpg: Can’t check signature: No public key’): import the developer’s public key (GPG will try to connect to the Internet using port TCP/11371):

$ gpg --keyserver pgp.mit.edu --recv-keys 0x518A031D

In case of error ‘gpg: keyserver receive failed: No dirmngr’:

$ sudo apt-get install dirmngr

d) Make sure the correct key was imported:

gpg: key 6DF634AA7608AF04: public key "Decred Release <release@decred.org>" imported

marcelo@fullnode:~/Downloads$ gpg --keyserver pgp.mit.edu --recv-keys 0x518A031D
gpg: key 6DF634AA7608AF04: public key "Decred Release <release@decred.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1

e) Verify the digital signature:

$ gpg --verify manifest-decrediton-$VERSION.txt.asc

gpg: assuming signed data in 'manifest-decrediton-v1.1.3.txt'
gpg: Signature made Thu Dec 21 17:15:58 2017 WET
gpg:                using RSA key 6D897EDF518A031D
gpg: Good signature from "Decred Release <release@decred.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: FD13 B683 5E24 8FAF 4BD1  838D 6DF6 34AA 7608 AF04
     Subkey fingerprint: F516 ADB7 A069 852C 7C28  A02D 6D89 7EDF 518A 031D

f) Look in the gpg output for: “using RSA key 6D897EDF518A031D” (only when verifying for the first time after importing the key). Notice that the second half of the RSA key, shown in the third line above, is shown in step c) and also the text ‘Good signature from “Decred Release”’

g) To generate the hash and manually compare it with the hashes inside manifest-decrediton-$VERSION.txt:

$ sha256sum decrediton-$VERSION.tar.gz
$ cat manifest-decrediton-$VERSION.txt

h) There is nothing to install. Extract; enter the directory; execute:

$ tar -xvzf decrediton-$VERSION.tar.gz
$ cd decrediton-$VERSION
$ ./decrediton

Warning in GPG output: Read more about Web of Trust in section 4.1.

Reference: https://docs.decred.org/advanced/verifying-binaries/

Obs.: If you don’t have gpg, go to https://gpgtools.org/

4.4. Windows

a) Go to https://github.com/decred/decred-binaries/releases/

b) Download to the same directory the files decrediton-$VERSION.exe, manifest-decrediton-$VERSION.txt and manifest-decrediton-$VERSION.txt.asc

c) In case the key hasn’t already been imported (error: ‘gpg: Can’t check signature: No public key’): import the developer’s public key (GPG will try to connect to the Internet using port TCP/11371):

> gpg --keyserver pgp.mit.edu --recv-keys 0x518A031D

d) Make sure the correct key was imported:

gpg: key 6DF634AA7608AF04: public key "Decred Release <release@decred.org>" imported

e) Verify the digital signature:

> gpg --verify manifest-decrediton-$VERSION.txt.asc

gpg: assuming signed data in 'manifest-decrediton-v1.1.3.txt'
gpg: Signature made Thu Dec 21 17:15:58 2017 WET
gpg:                using RSA key 6D897EDF518A031D
gpg: Good signature from "Decred Release <release@decred.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: FD13 B683 5E24 8FAF 4BD1  838D 6DF6 34AA 7608 AF04
     Subkey fingerprint: F516 ADB7 A069 852C 7C28  A02D 6D89 7EDF 518A 031D

f) Look in the gpg output for: “using RSA key 6D897EDF518A031D” (only when verifying for the first time after importing the key). Notice that the second half of the RSA key, shown in the third line above, is shown in step c) and also the text ‘Good signature from “Decred Release”’

g) Windows doesn’t come with a native tool to generate SHA256 hashes. Windows users may try the tool PowerShell File Checksum Integrity Verifier (PsFCIV) available at Microsoft Technet.

Warning in GPG output: Read more about Web of Trust in section 4.1.

Reference: https://docs.decred.org/advanced/verifying-binaries/

Obs.: If you don’t have gpg, go to https://gpgtools.org/