The goal is to have a long message as input and produce an output which is much shorter, called the hash or message digest. Furthermore, we want it to have certain properties.
-**Input**: long message
-**Output**: short fixed size block (called hash or message digest)
*We want the same input always produces the same output (deterministic)*
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- A *non* security related example of hash functions?
- A security related example of hash functions?
%% Cell type:markdown id: tags:
*** There is a difference between hash functions and cryptographic hash functions ***
%% Cell type:markdown id: tags:
### Desired properties
- Pre-image: Given a hash $h$ it is computationally infeasible to find a message $m$ that produces $h$
- Second preimage: Given message m, it is computationally infeasible to find a message $m’$, ($m ≠ m’$) such that, $h(m) = h(m’)$
- Collisions: It is computationally difficult to find any two messages $m, m’$ $(m ≠ m’)$ such that, $h(m) = h(m’)$
**Examples**:
- Recommended Hash Algorithm (SHA-2, SHA-3) by NIST
-<strike>SHA-1</strike>: output 160 bits being phased out (shattered.io)
-<strike>MD2, MD4, and MD5</strike> by Ron Rivest [RFC1319, 1320, 1321]
Secure Hash Algorithm (SHA) family, is a series of hashing algorithms. Ranging from SHA-0 to SHA-3. SHA-0 should never be used, it's advised to move from SHA-1 to SHA-2. SHA-3 is the most recent version, standardized by NIST.
- Let's explore what other hashing algorithms are available and use a different one.
- Change "O'ReillyCrypto", to "O'Reilly Crypto" and see check the result
%% Cell type:markdown id: tags:
### Python Builtin Support
%% Cell type:markdown id: tags:
*"Additional algorithms may also be available depending upon the OpenSSL library that Python uses on your platform. On most platforms the sha3_224(), sha3_256(), sha3_384(), sha3_512(), shake_128(), shake_256() are also available."*
- Let's explore the impact of the size of the message on the speed of our hashing
%% Cell type:markdown id: tags:
## *<font color=" #b74138">Solution</font>*
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
### Hash-based message authentication code (HMAC)
HMACs are used for message authentications combined with a secret key. This provide integrity check and authentication. An attacker can not forge the digest without knowing the secret key. Same message produces different digests for different keys.
Generally speaking there are two *kinds* of encryptions. Symmetric and Asymmetric.
In the symmetric encryption the parties involved share the ***same*** key.
In the asymmetric encryption schemes the parties use ***different*** keys, that are mathematically ***related*** to each other.
<imgsrc="include/sym_vs_asym.png"width="700">
%% Cell type:markdown id: tags:
## Symmetric Encryption
In the following we look at the symmetric encryption algorithms. In symmetric crypto, we use the same key for encryption and decryption. **Therefore, the two parties needs to establish a secret key between them.** Symmetric encryption can be up to 1000 times faster than asymmetric encryption. Given the support of some crypto algorithm in the CPU and at hardware level, even faster.
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- How should we share this secret key? securely, of course!
%% Cell type:markdown id: tags:
### Advanced Encryption Algorithm (AES)
AES is based on Rijndael encryption algorithm, designed by Joan Daemen and Vincent Rijmen. It was one of the algorithms submitted to U.S. National Institute of Standards and Technology (NIST) to replace DES and 3DES. It was published in 1998 and accepted and standardized in 2001.
* AES supports key sizes of 128/192/256 bits
* Block size: 128 bit
* It's iterative rather than Feistel cipher
* Treats data in 4 groups of 4 bytes
* Operates on an entire block in every round
* Resistant against known attacks
* Speed and code compactness on many CPUs
* Rijndael block and key size vary between 128, 192, 256
* However, in AES block size in 128
* Number of rounds a function of key size
* 128 bits 10 rounds
* 192 bits 12 rounds
* 256 bits 14 rounds
* Today most implementations use the CPU support (Intel AES-NI)
%% Cell type:markdown id: tags:
### Block cipher mode of operation
To encrypt messages of arbitrary size with block ciphers, we use the following algorithms, called the modes of operation. They define how to encrypt each block of the plaintext to produce the corresponding cipher text block. Some of these are completely insecure (ECB) and should not be used.
Encryptingyoudataalonewillnotprotectyoufromdatatampering.Meaninganadversarycanchangetheresultsofyourdecryptionwithouthavingaccesstothekey.All,withoutyounoticing.That's when are HMACs from previously become handy.
%% Cell type:markdown id: tags:
### Bit flipping attack
%% Cell type:markdown id: tags:
Since the IV is sent in clear we can change the IV value and change the corresponding plaintext, when using CBC mode.
***Encryption***
- $C_{i}=E_{K}(P_{i}\oplus C_{i-1})$
- $ C_{0}=IV$
***Decryption***
- $P_{i}=D_{K}(C_{i})\oplus C_{i-1}$
- $C_{0}=IV$
Therefore to change the plaintext value we just need to xor the old plaintext(p), and the new value (t), with the IV:
$IV = IV \oplus p \oplus t$
Meaning if the first 4 bytes of the plaint text are: "1234" and we want to change it to "6789" all we have to do is
$IV[0:4] = IV[0:4] \oplus 1234 \oplus 6789$
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- Imagine the message is only 16 bytes, "O'ReillyCrypto19". Change the year from 19 to 20 by modifying the value of IV.
## Authenticated Encryption with Associated Data (AEAD)
AEAD provides confidentiality, integrity, and authenticity at once. Such schemes help to mitigate against the bit flipping attacks that we just did. The Galois/Counter Mode (GCM) mode of operation is the recommended schemes to be used. Fortunately, the *cryptography* library already has it implemented.
Reminder: In the asymmetric encryption schemes the parties use ***different*** keys, that are mathematically ***related*** to each other.
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- Why asymmetric encryption is useful?
- Give a few examples where it can be used?
%% Cell type:markdown id: tags:
## RSA
RSA, is an asymmetric encryption algorithm by Ron Rivest, Adi Shamir, and Leonard Adleman. It was published in 1977. It's security is based on the hardness of factorization problem. However, now it has its own problem, called the RSA problem. RSA is slow, and is not used for encrypting large data, but it's mostly used to encrypt the symmetric key that is used for encryption.
openssl rsa -in private_key.pem -pubout -outform DER -out public_key.der
```
%% Cell type:code id: tags:
``` python
# import key from a file. E.g., previously generated by OpenSSL
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
with open("private_key.pem", "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None,
backend=default_backend())
public_key = private_key.public_key()
```
%% Cell type:code id: tags:
``` python
# Generate a 2048 bit private key
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend())
# to get the public key
public_key = private_key.public_key()
```
%% Cell type:code id: tags:
``` python
2 ** 16 +1
```
%% Cell type:code id: tags:
``` python
print(bin(2**16 + 1))
print(bin(2**1 + 1))
```
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- What's wrong with textbook RSA?
%% Cell type:markdown id: tags:
### It's all about padding and randomness
%% Cell type:markdown id: tags:
### Optimal Asymmetric Encryption Padding (OAEP)
Textbook RSA is not IND-CPA secure, therefore we use Optimal Asymmetric Encryption Padding (OAEP).
<img src="include/RSA_OAEP.png">
image souce: wikipedia
%% Cell type:code id: tags:
``` python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
message = b"Y"*127
ciphertext = public_key.encrypt(
message,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA1()),
algorithm=hashes.SHA1(),
label=None))
```
%% Cell type:code id: tags:
``` python
print(ciphertext)
```
%% Cell type:code id: tags:
``` python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
plaintext = private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA1()),
algorithm=hashes.SHA1(),
label=None))
```
%% Cell type:code id: tags:
``` python
print(plaintext)
```
%% Cell type:markdown id: tags:
### Probabilistic Signature Scheme (PSS)
%% Cell type:code id: tags:
``` python
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
message = b"Message to be signed"
```
%% Cell type:code id: tags:
``` python
# signature creation
signature = private_key.sign(
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH),
hashes.SHA256())
```
%% Cell type:code id: tags:
``` python
# signature verification
public_key.verify(
signature,
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH),
hashes.SHA256())
```
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- Compare the speed of encryption using RSA-2048 and AES-128.
%% Cell type:markdown id: tags:
## *<font color=" #b74138">Solution</font>*
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
These tests give an idea of the speed difference between RSA and AES. However, our benchmark does not reflect the whole picture. To get a better view run:
``` bash
$ openssl speed rsa aes
```
%% Cell type:markdown id: tags:
## Diffie–Hellman key exchange
%% Cell type:markdown id: tags:
Diffie-Hellman is a key exchange protocol and an example of an asymmetric cryptography. Named after it's inventors Whitfield Diffie and Martin Hellman in 1976. The security of DH key exchange relies on the hardness of discrete logarithm.
%% Cell type:markdown id: tags:
- Alice: generate private key ($a$). Calculate public key $A = (g ^ a)$ mod $p$
- Bob: generate private key ($b$). Calculate public key $B = (g ^ b)$ mod $p$
- Alice -> Bob: Alice sends her public key ($A$) to Bob
- Bob -> Alice: Bob send his public key ($B$) to Alice
- Alice and Bob: Calculate shared key K = $g ^ {ab}$ mod $p$
- $(g ^ a) ^ b = (g ^ b) ^ a = g ^ {ab}$
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- Perform basic DH key exchange using the values below to create a shared key ($g^{ab}$)
%% Cell type:code id: tags:
``` python
g = 2
p = 19
a = 7
b = 8
```
%% Cell type:markdown id: tags:
## *<font color=" #b74138">Solution</font>*
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
### Performing DH key exchange with key derivation
%% Cell type:code id: tags:
``` python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import dh
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
ECC is another asymmetric approach that is based on elliptic curves over finite fields. ECC is a more recent approach compared to RSA. They key sizes in ECC are smaller than RSA. As a result it can consume less resources and is popular in environments with constrained resources such as IoT devices and sensors.
%% Cell type:code id: tags:
``` python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric import ec
Changes for notebooks/6. Full Cryptographic Protocols.ipynb: 5 added lines, 0 removed lines.
Original line number
Diff line number
Diff line
%% Cell type:markdown id: tags:
# Cryptographic Protocols
%% Cell type:markdown id: tags:
Transport Layer Security (TLS) and Pretty Good Privacy (PGP) are examples of cryptographic protocols that combine the cryptographic primitives that we learned about in previous sections.
%% Cell type:markdown id: tags:
# Transport Layer Security (TLS)
TLS Formerly known as Secure Sockets Layer (SSL) is a cryptographic protocol suite to secure data in transfer. It is widely used over internet with different protocols such as HTTP, FTP, SMTP, etc. Different cipher suites provides variety of security protection services based on the users' needs.
<imgsrc="include/tls_http.png"width=800>
%% Cell type:markdown id: tags:
# Pretty Good Privacy (PGP)
- A data encryption/decryption tool
- Can be used to encrypt and authenticat email, files, etc.
- Created by Phil Zimmermann in 1991
- A practical hybrid system that uses symmetric and asymmetric crypto
<imgsrc="include/PGP_diagram.png"width=500>
image source: wikipedia
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- Implement PGP to encrypt some content as shown in the diagram above. Use AES in GCM mode.
Reminder: In the asymmetric encryption schemes the parties use ***different*** keys, that are mathematically ***related*** to each other.
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- Why asymmetric encryption is useful?
- Give a few examples where it can be used?
%% Cell type:markdown id: tags:
## RSA
RSA, is an asymmetric encryption algorithm by Ron Rivest, Adi Shamir, and Leonard Adleman. It was published in 1977. It's security is based on the hardness of factorization problem. However, now it has its own problem, called the RSA problem. RSA is slow, and is not used for encrypting large data, but it's mostly used to encrypt the symmetric key that is used for encryption.
- Perform textbook RSA encryption and decryption using the values from the example
%% Cell type:code id: tags:
``` python
p=5
q=11
n=p*q
e=3
d=27
m=2
```
%% Cell type:markdown id: tags:
## *<font color=" #b74138">Solution</font>*
%% Cell type:code id: tags:
``` python
e*d
```
%% Cell type:code id: tags:
``` python
e*d%((p-1)*(q-1))
```
%% Cell type:code id: tags:
``` python
c=m**e
print(c)
```
%% Cell type:code id: tags:
``` python
c=m**e%n
print(c)
```
%% Cell type:code id: tags:
``` python
c=pow(m,e,n)
print(c)
```
%% Cell type:code id: tags:
``` python
c**d
```
%% Cell type:code id: tags:
``` python
m_dec=c**d%n
print(m_dec)
```
%% Cell type:code id: tags:
``` python
m_dec=pow(c,d,n)
print(m_dec)
```
%% Cell type:markdown id: tags:
### Signing
The purpose of signatures is to prove the "creator" of a message. To perform this task we use the private key, since only the owner of the keypair is aware of the private key. Everyone with the knowledge of the public key can verify the signature.
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- Create textbook RSA signature on message (m=2). Use the private key (d), instead of the public key (e) to generate the signature. Use the public key (e) to verify the signature.
print("RSA: Encrypted {} messages in {} seconds".format(loops, e-s))
s = time.time()
for i in range(loops):
aes_128_enc(message)
e = time.time()
print("AES: Encrypted {} messages in {} seconds".format(loops, e-s))
```
%% Cell type:markdown id: tags:
These tests give an idea of the speed difference between RSA and AES. However, our benchmark does not reflect the whole picture. To get a better view run:
``` bash
$ openssl speed rsa aes
```
%% Cell type:markdown id: tags:
## Diffie–Hellman key exchange
%% Cell type:markdown id: tags:
Diffie-Hellman is a key exchange protocol and an example of an asymmetric cryptography. Named after it's inventors Whitfield Diffie and Martin Hellman in 1976. The security of DH key exchange relies on the hardness of discrete logarithm.
%% Cell type:markdown id: tags:
- Alice: generate private key ($a$). Calculate public key $A = (g ^ a)$ mod $p$
- Bob: generate private key ($b$). Calculate public key $B = (g ^ b)$ mod $p$
- Alice -> Bob: Alice sends her public key ($A$) to Bob
- Bob -> Alice: Bob send his public key ($B$) to Alice
- Alice and Bob: Calculate shared key K = $g ^ {ab}$ mod $p$
- $(g ^ a) ^ b = (g ^ b) ^ a = g ^ {ab}$
%% Cell type:markdown id: tags:
## *<font color=" #6495ED">Exercise</font>*
- Perform basic DH key exchange using the values below to create a shared key ($g^{ab}$)
%% Cell type:code id: tags:
``` python
g = 2
p = 19
a = 7
b = 8
```
%% Cell type:markdown id: tags:
## *<font color=" #b74138">Solution</font>*
%% Cell type:code id: tags:
``` python
gab = pow(pow(g, a, p), b, p) # (g^a) ^ b
print(gab)
```
%% Cell type:code id: tags:
``` python
gba = pow(pow(g, b, p), a, p) # (g^b) ^ a
print(gba)
```
%% Cell type:code id: tags:
``` python
assert gab == gba
```
%% Cell type:markdown id: tags:
### Performing DH key exchange with key derivation
%% Cell type:code id: tags:
``` python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import dh
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
ECC is another asymmetric approach that is based on elliptic curves over finite fields. ECC is a more recent approach compared to RSA. They key sizes in ECC are smaller than RSA. As a result it can consume less resources and is popular in environments with constrained resources such as IoT devices and sensors.
%% Cell type:code id: tags:
``` python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric import ec