openssl is a project comprising (1) a core library and (2 ... · pdf fileopenssl is a project...

24
1

Upload: tranngoc

Post on 05-Mar-2018

216 views

Category:

Documents


0 download

TRANSCRIPT

1

2

OpenSSL is a project comprising (1) a core library and (2) a toolkit. The core library offers an API for developers of secure applications. The toolkit offers a series of command-line tools to perform basic security operations (for example certificate creation, digests, etc.)

OpenSSL is pre-installed in the majority of Unix-like systems. On Microsoft system, it is provided within the Cygwin package. Cygwin is a library offering a Unix-like API (through cygwin.dll) plus a collection of Unix-like command-line tools. It comprises the OpenSSL package as well as the gcc compiler.

3

The OpenSSL library is logically divided in different headers: openssl/crypto.h offering basic ciphers; openssl/evp.h offering a high-level interface to the crypto.h operations; openssl/ssh.h offering secure transport protocols (SSL, TLS, DTLS); openssl/rand.h offering routines for the generation of pseudo-random quantities.

4

5

The logical representation of an encryption is a function, taking a key and a variable-sized plaintext as input, and returning a variable-sized ciphertext as output.

Implementing encryption and decryption in this way is not efficient neither practical. It is not efficient because if the plaintext is big, we have to maintain in memory a big quantity of data at once. It is not practical because sometimes we do not have the entire plaintext/ciphertext at the time we must encrypt/decrypt it. This is typical in encrypted communications.

The majority of cryptographic libraries uses incremental functions, which update an encryption context step-by-step. This is done in higher-level languages as well, for example Java and C#.

6

This slide shows the pseudo-code of an incremental encryption operation. We must first initialize the context, giving the various parameters (cipher, mode, key, iv). Then we cycle giving a series of plaintext fragments to the encrypter (context update). The encrypter gives back a series of ciphertext fragments. Finally, we finalize the context, retrieving the last ciphertext fragment.

The decryption operation is done in the same fashion.

7

Since the encryption works on blocks of fixed size, the finalize function adds the necessary padding. OpenSSL uses the PKCS#7 standard for the padding, by which the padding bytes have the same value of the padding length (e.g. 6 bytes each of value 6). The padding is ALWAYS added, so if the plaintext length is already a block multiple, a block-long padding is added. As a consequence, the ciphertext length is always (strictly) greater than the plaintext length.

To retrieve correctly the original plaintext, the decrypter must know its length. Otherwise, he does not know where the plaintext ends and the padding begins.

The decrypt finalize function also checks for the validity of the padding. If the padding is not valid, the ciphertext is surely corrupt, so the decrypted data must be discarded. However, this is not a secure method for message authentication (there are ~1/256 probability that a corrupted ciphertext is taken as valid).

8

These OpenSSL API functions realizes the incremental encryption/decryption. The length of the fragments returned by EVP_EncryptUpdate, EVP_EncryptFinal,

EVP_DecryptUpdate, EVP_DecryptFinal is always multiple of the block. The buffer containing the ciphertext must always be larger than the one containing the plaintext. Allocating len_plaintext+block_size is safe.

Pay attention to not overwrite the fragment returned by EVP_EncryptUpdate with the one returned by EVP_EncryptFinal. A counter or a shifting pointer to the buffer must be used.

EVP_EncryptFinal adds the necessary padding. EVP_DecryptFinal checks for the validity of the padding (if it is not valid, it returns 0) and discards it. So the final fragment returned by EVP_DecryptFinal does NOT include the padding.

9

Note for DES: Even if the DES key has 56 bits, it is always mapped on 64 bits. OpenSSL also uses this convention.

10

The generation of pseudo-random numbers is often an underrated aspect of security systems, causing many vulnerabilities. Generating good (i.e. truly unpredictable) random numbers requires to select good seeds (or entropy sources), which is not easy.

There are many way to add entropy to the pseudo-random number generator (PRNG). Possible entropy sources are:

- the system clock, - the content of unallocated memory, - the user's input (mouse, keyboard), - the current content on the display, - hardware entropy generators, - software entropy-generator daemons (which in turn takes entropy from the above

sources).

11

12

13

The buffer plaintext will contain the decrypted text, which must coincide with the original message.

14

I create a random key. For this toy program, I do not add entropy in the PRNG before doing this.

15

I create and initialize the context. For this toy program, I use DES cipher in ECB mode, which is very insecure.

16

I encrypt the message with a single step (one “update” and one “final”). For short text it is ok. Longer plaintexts require multiple steps.

17

I must check EVP_DecryptFinal for errors, as this function checks the validity of the padding.

18

19

This is the output of the example program.

20

Note that the ECB mode is vulnerable to electronic-codebook analysis, because the same plaintext block results in the same ciphertext block. To avoid this, we have to use more advanced modes, like CBC.

21

This slide shows the most common ciphers (plus the modes) used in OpenSSL. It is recommended to always use AES, the other ciphers are obsolete and insecure. AES with 128-bit keys (in CBC mode) is fine for 99% of applications. Use AES with 256-bit keys (in CBC mode) only if you want TOP SECRET security (less efficient than 128-bit keys).

22

23

24