~
My notes when reading Real-World Cryptography
... convert from input to digest
... produce from key, message to authentication tag.
sequenceDiagram
participant alice
participant bob
alice ->> bob: send alice, mac(secret_key_alice, alice)
bob ->> bob: compare mac(secret_key_alice, alice) with mac(secret_key_bob, alice)
Constant time comparison:
for i := 0; i < len(x); i++ {
// Use XOR instead of compare x[i] == y[i]
// If x[i] == y[i] -> XOR is 1
// Otherwise XOR is 0
v |= x[i] ^ y[i]
}
// v == 1 means all XOR is 1 means x == y
Use for:
sequenceDiagram
participant alice
participant bob
alice ->> bob: send username, password
bob -->> alice: return alice|mac(secret_key, alice)
alice ->> bob: send alice|mac(secret_key, alice)
bob -->> alice: return OK
alice ->> bob: send bob|mac(secret_key, alice)
bob -->> alice: return ERROR
HMAC is MAC using hash
Currently (2023) the world using AES-128 which take a key 128 bits == 16 bytes
AES is kind of cipher, handle fixed-size plaintext so we called block cipher. AES is deterministic so we can encrypt and decrypt.
What if text you want to encrypt is longer than 128 bytes ? We add padding for text to become multi block which has 128 bytes, then encrypt each block.
Adding padding bytes is easy, remove it after decrypt is hard. How do you know which is padding bytes you add if you use random bytes ?
Just use PKCS#7 padding. Example AES-128 use block of 16
bytes but only have 9 bytes, should add 7 bytes padding. Just fill all
padding bytes with padding length aka value 07
.
XX XX XX XX XX XX XX XX XX 07 07 07 07 07 07 07
So to know how much padding bytes should we remove -> read last bytes
(07
) to know the length to remove trailing padding bytes.
The problem with naive way to split text, add padding bytes then encrypt each block using AES-128 is repeated text. Because it leaks information if text is made up from many repeated text (See The ECB penguin).
CBC = deterministic block cipher + IV (initialization vector)
AES-CBC encrypt:
AES-CBC decrypt:
Because IV, same plaintext can encrypt to different ciphertext.
WARNING If IV become predictable, AES-CBC become deterministic -> BEAST attack (Browser Exploit Against SSL/TLS).
Because AES-CBC requires IV which shows public -> attacker can change IV -> lack of authenticity -> use AES-CBC-HMAC or AEAD.
AEAD provides a way to authenticate associated data.
... is one of AEAD implementation.
AES-GCM = AES-CTR (Counter) + GMAC message authentication code
AES-CTR encrypt:
Limit is counter only up to 4 bytes so only handle plaintext of 2^32 - 1 blocks of 16 bytes aka 69 GBs.
AES-CTR no need padding because if keystream is longer than plaintext, it is truncated to plaintext length before XOR.
This is stream cipher, differ from block cipher
GMAC is MAC with GHASH. GHASH resembles CBC mode.
... is one of AEAD implementation.
ChaCha20-Poly1305 = ChaCha20 stream cipher + Poly1305 MAC
sequenceDiagram
participant alice
participant bob
alice ->> alice: generate key pair: public_key, secret_key
bob ->> bob: generate key pair: public_key, secret_key
alice ->> bob: send public_key
bob ->> alice: send public_key
alice ->> alice: generate shared_secret(secret_key, bob_public_key)
bob ->> bob: generate shared_secret(secret_key, alice_public_key)
Prevent MITM (Man In The Middle) passive attack. If attacker can intercept public_key then it's over.
... is key exchange algorithm.
p
and generator
g
.
a
and public
A = g^a mod p
.
b
and public
B = g^b mod p
.
A
and B
A^b mod p == B^a mod p == g^(ab) mod p
Diffie-Hellman is based on group theory.
Instead of prime number, use elliptic curve.
E
and generator
G
.
a
and public A = [a]G
.
b
and public B = [b]G
.
A
and B
[a]B == [b]A == [ab]G