Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Symmetric encryption requires the users to find a secure channel to exchange keys. By secure channel, we are mainly concerned with confidentiality and integrity. In other words, we need a channel where no third party can eavesdrop and read the traffic; moreover, no one can change the sent messages and data.

Asymmetric encryption makes it possible to exchange encrypted messages without a secure channel; we just need a reliable channel. By reliable channel, we mean that we are mainly concerned with the channel’s integrity and not confidentiality.

When using an asymmetric encryption algorithm, we would generate a key pair: a public key and a private key. The public key is shared with the world, or more specifically, with the people who want to communicate with us securely. The private key must be saved securely, and we must never let anyone access it. Moreover, it is not feasible to derive the private key despite the knowledge of the public key.

How does this key pair work?

If a message is encrypted with one key, it can be decrypted with the other. In other words:

  • If Alice encrypts a message using Bob’s public key, it can be decrypted only using Bob’s private key.
  • Reversely, if Bob encrypts a message using his private key, it can only be decrypted using Bob’s public key.

Confidentiality

We can use asymmetric encryption to achieve confidentiality by encrypting the messages using the recipient’s public key. In the following two figures, we can see that:

Alice wants to ensure confidentiality in her communication with Bob. She encrypts the message using Bob’s public key, and Bob decrypts them using his private key. Bob’s public key is expected to be published on a public database or on his website, for instance.

When Bob wants to reply to Alice, he encrypts his messages using Alice’s public key, and Alice can decrypt them using her private key.

In other words, it becomes easy to communicate with Alice and Bob while ensuring the confidentiality of the messages. The only requirement is that all parties have their public keys available for interested senders.

Note: In practice, symmetric encryption algorithms allow faster operations than asymmetric encryption; therefore, we will cover later how we can use the best of both worlds.

Integrity, Authenticity, and Nonrepudiation

Beyond confidentiality, asymmetric encryption can solve integrity, authenticity and nonrepudiation. Let’s say that Bob wants to make a statement and wants everyone to be able to confirm that this statement indeed came from him. Bob needs to encrypt the message using his private key; the recipients can decrypt it using Bob’s public key. If the message decrypts successfully with Bob’s public key, it means that the message was encrypted using Bob’s private key. (In practice, he would encrypt a hash of the original message. We will elaborate on this later.)

Being decrypted successfully using Bob’s public key leads to a few interesting conclusions.

  • First, the message was not altered across the way (communication channel); this proves the message integrity.
  • Second, knowing that no one has access to Bob’s private key, we can be sure that this message did indeed come from Bob; this proves the message authenticity.
  • Finally, because no one other than Bob has access to Bob’s private key, Bob cannot deny sending this message; this establishes nonrepudiation.

We have seen how asymmetric encryption can help establish confidentiality, integrity, authenticity, and nonrepudiation. In real-life scenarios, asymmetric encryption can be relatively slow to encrypt large files and vast amounts of data. In another task, we will see how we can use asymmetric encryption in conjunction with symmetric encryption to achieve these security objectives relatively faster.

RSA

RSA got its name from its inventors, Rivest, Shamir, and Adleman. It works as follows:

  1. Choose two random prime numbers, p and q. Calculate N = p × q.
  2. Choose two integers e and d such that e × d = 1 mod ϕ(N), where ϕ(N) = N − p − q + 1. This step will let us generate the public key (N,e) and the private key (N,d).
  3. The sender can encrypt a value x by calculating y = x__e mod N. (Modulus)
  4. The recipient can decrypt y by calculating x = y__d mod N. Note that y__d = x__e__d = x__k__ϕ(N) + 1 = (x__ϕ(N))k × x = x. This step explains why we put a restriction on the choice of e and d.

Don’t worry if the above mathematical equations looked too complicated; you don’t need mathematics to be able to use RSA, as it is readily available via programs and programming libraries.

RSA security relies on factorization being a hard problem. It is easy to multiply p by q; however, it is time-consuming to find p and q given N. Moreover, for this to be secure, p and q should be pretty large numbers, for example, each being 1024 bits (that’s a number with more than 300 digits). It is important to note that RSA relies on secure random number generation, as with other asymmetric encryption algorithms. If an adversary can guess p and q, the whole system would be considered insecure.

Let’s consider the following practical example.

  1. Bob chooses two prime numbers: p = 157 and q = 199. He calculates N = 31243.
  2. With ϕ(N) = N − p − q + 1 = 31243 − 157 − 199 + 1 = 30888, Bob selects e = 163 and d = 379 where e × d = 163 × 379 = 61777 and 61777 mod 30888 = 1. The public key is (31243,163) and the private key is (31243,379).
  3. Let’s say that the value to encrypt is x = 13, then Alice would calculate and send y = x__e mod N = 13163 mod 31243 = 16341.
  4. Bob will decrypt the received value by calculating x = y__d mod N = 16341379 mod 31243 = 13.

The previous example was to understand the mathematics behind it better. To see real values for p and q, let’s create a real keypair using a tool such as openssl.

Terminal

       `user@TryHackMe$ openssl genrsa -out private-key.pem 2048  user@TryHackMe$ openssl rsa -in private-key.pem -pubout -out public-key.pem writing RSA key  user@TryHackMe$ cat public-key.pem -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAymcAeYg1ohPQLHu7u9l1 UutN8bCP7r6czRX2zrQrpElYrm5mHERi1xweWEhTJ/0Q13FJcHLGtLbdQc0rGpOd DnYJBuzrqXU2hC7E7dlqLsj63NPADqlOGYCGCWnm/HGM2WuVtDXqRitN4zeNKEWI QmEctfucopZx5AVJ1vTn+qMv/0D6QU7Mm65MTSYg1SCRA0D0N9NLMj4rYlLOIr5q 5g3iunAE4tCROMcHf7fxWMuWdJTdtxTv7+4P5XGkWrWriO22JFHp9N22Fm96V9jH 7aASRkIZvQFmx+1dl7btZDhsm2ezU07LBabv9efj0gIwz6P3mTJVm+wxaDH6jiXB dwIDAQAB -----END PUBLIC KEY-----  user@TryHackMe$ openssl rsa -in private-key.pem -text -noout Private-Key: (2048 bit, 2 primes) modulus:     00:ca:67:00:79:88:35:a2:13:d0:2c:7b:bb:bb:d9:     75:52:eb:4d:f1:b0:8f:ee:be:9c:cd:15:f6:ce:b4:     2b:a4:49:58:ae:6e:66:1c:44:62:d7:1c:1e:58:48:     53:27:fd:10:d7:71:49:70:72:c6:b4:b6:dd:41:cd:     2b:1a:93:9d:0e:76:09:06:ec:eb:a9:75:36:84:2e:     c4:ed:d9:6a:2e:c8:fa:dc:d3:c0:0e:a9:4e:19:80:     86:09:69:e6:fc:71:8c:d9:6b:95:b4:35:ea:46:2b:     4d:e3:37:8d:28:45:88:42:61:1c:b5:fb:9c:a2:96:     71:e4:05:49:d6:f4:e7:fa:a3:2f:ff:40:fa:41:4e:     cc:9b:ae:4c:4d:26:20:d5:20:91:03:40:f4:37:d3:     4b:32:3e:2b:62:52:ce:22:be:6a:e6:0d:e2:ba:70:     04:e2:d0:91:38:c7:07:7f:b7:f1:58:cb:96:74:94:     dd:b7:14:ef:ef:ee:0f:e5:71:a4:5a:b5:ab:88:ed:     b6:24:51:e9:f4:dd:b6:16:6f:7a:57:d8:c7:ed:a0:     12:46:42:19:bd:01:66:c7:ed:5d:97:b6:ed:64:38:     6c:9b:67:b3:53:4e:cb:05:a6:ef:f5:e7:e3:d2:02:     30:cf:a3:f7:99:32:55:9b:ec:31:68:31:fa:8e:25:     c1:77 publicExponent: 65537 (0x10001) privateExponent:     10:fe:00:be:33:3f:3d:72:28:61:f3:a9:59:25:f2:     81:99:9b:9b:94:d5:20:98:04:15:fb:a8:12:c6:71:     7b:83:64:dc:90:0c:26:87:5f:3c:eb:f1:68:3b:fa:     2f:3b:41:b4:b4:a0:13:be:af:0b:f0:e6:36:66:01:     1e:64:12:25:6a:a7:6b:5b:6c:95:77:6f:b2:3d:32:     ef:3c:f7:7b:22:08:5d:8d:b1:6c:09:ae:b2:d9:65:     67:58:ea:b9:7a:d6:f6:51:df:e9:97:35:29:da:ec:     d9:0c:8a:df:3c:a7:29:db:79:4b:95:ea:1a:84:42:     df:7f:ca:29:2f:ba:62:02:37:05:c0:b0:c2:ff:42:     6b:fb:e1:36:40:10:ae:11:0f:d8:87:2f:fe:10:2e:     a4:60:de:ff:fe:c8:ab:0b:29:fa:6c:20:ec:87:33:     46:c0:cd:96:36:cb:9b:ca:81:17:e5:c3:eb:34:b2:     83:0f:52:cc:e9:68:bd:cb:d2:85:2f:fe:c4:47:76:     df:94:69:ce:7b:8a:50:71:36:96:e6:35:fb:fb:b4:     4a:ac:63:9b:9d:1b:bb:32:71:31:45:a2:25:33:cc:     f7:a5:fb:9f:66:b1:4e:30:ce:9d:71:e8:fa:7d:5f:     33:a0:c1:94:0a:b7:b7:f3:16:7e:4f:ad:89:3d:ba:     51 prime1:     00:e0:3d:87:b3:d3:1f:d2:c6:66:23:83:a5:95:d5:     20:35:f8:d8:c0:94:cf:cc:d2:04:d4:e4:ef:cf:c2:     94:00:10:cd:d1:4a:df:09:4e:7e:95:f8:70:08:b1:     20:98:8a:e3:88:f7:cc:a8:32:62:32:68:f6:1f:c0:     fb:c1:71:41:8c:21:a3:ff:20:e6:96:d0:6e:4b:66:     61:08:d0:b7:26:48:27:62:a7:d3:ff:36:55:c8:e1:     ab:91:48:90:fb:b5:b1:92:be:90:06:a8:40:1b:2a:     2d:53:1e:87:fc:a7:8a:57:72:0b:e5:35:71:7b:dd:     8c:e5:b5:ab:64:7c:37:c5:0d prime2:     00:e7:11:ac:50:f5:dc:16:cf:20:46:77:5d:ca:16:     29:36:35:89:95:c0:f8:4b:42:ef:03:a0:f1:ce:2e:     1b:da:55:a9:ff:5a:28:4d:78:c5:8a:e2:55:9b:94:     b4:56:ec:ab:1b:dd:b8:07:be:dd:d5:0f:49:90:b3:     ed:a2:d7:78:38:24:d5:9e:7d:a2:e8:8c:e0:2a:33:     32:21:1f:0e:6b:aa:0b:b4:11:6a:bd:8f:d9:86:3f:     ad:42:c8:bc:42:23:21:39:8d:0c:60:f2:ca:2a:00:     0a:8e:de:fb:1a:3c:51:9d:f2:dc:0a:59:80:d6:a4:     47:5c:02:a3:d0:30:1d:47:93 [...]`

We executed three commands:

  • openssl genrsa -out private-key.pem 2048: With openssl, we used genrsa to generate an RSA private key. Using -out, we specified that the resulting private key is saved as private-key.pem. We added 2048 to specify a key size of 2048 bits.
  • openssl rsa -in private-key.pem -pubout -out public-key.pem: Using openssl, we specified that we are using the RSA algorithm with the rsa option. We specified that we wanted to get the public key using -pubout. Finally, we set the private key as input using -in private-key.pem and saved the output using -out public-key.pem.
  • openssl rsa -in private-key.pem -text -noout: We are curious to see real RSA variables, so we used -text -noout. The values of p, q, N, e, and d are prime1, prime2, modulus, publicExponent, and privateExponent, respectively.

If we already have the recipient’s public key, we can encrypt it with the command openssl pkeyutl -encrypt -in plaintext.txt -out ciphertext -inkey public-key.pem -pubin

The recipient can decrypt it using the command openssl pkeyutl -decrypt -in ciphertext -inkey private-key.pem -out decrypted.txt