294 lines
12 KiB
HTML
294 lines
12 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<link
|
|
rel="stylesheet"
|
|
href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.5.1/github-markdown.min.css"
|
|
/>
|
|
<title>haunt98 posts</title>
|
|
</head>
|
|
<style>
|
|
.markdown-body {
|
|
box-sizing: border-box;
|
|
min-width: 200px;
|
|
max-width: 980px;
|
|
margin: 0 auto;
|
|
padding: 45px;
|
|
}
|
|
|
|
@media (max-width: 767px) {
|
|
.markdown-body {
|
|
padding: 15px;
|
|
}
|
|
}
|
|
</style>
|
|
<body class="markdown-body">
|
|
<h2>
|
|
<a href="index.html"><code>~</code></a>
|
|
</h2>
|
|
<h1>
|
|
<a
|
|
id="user-content-real-world-crypto-101"
|
|
class="anchor"
|
|
aria-hidden="true"
|
|
tabindex="-1"
|
|
href="#real-world-crypto-101"
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
>Real World Crypto 101
|
|
</h1>
|
|
<p>
|
|
My notes when reading
|
|
<a
|
|
href="https://www.manning.com/books/real-world-cryptography"
|
|
rel="nofollow"
|
|
>Real-World Cryptography</a
|
|
>
|
|
</p>
|
|
<h2>
|
|
<a
|
|
id="user-content-hash-function-convert-from-input-to-digest"
|
|
class="anchor"
|
|
aria-hidden="true"
|
|
tabindex="-1"
|
|
href="#hash-function-convert-from-input-to-digest"
|
|
><span aria-hidden="true" class="octicon octicon-link"></span
|
|
></a>
|
|
<strong>Hash</strong> function convert from input to digest
|
|
</h2>
|
|
<ul>
|
|
<li>Pre-image resistance: Given digest, can not find input</li>
|
|
<li>
|
|
Second pre-image resistance: Given input, digest, can not find another
|
|
input produce same digest. Small change to input make digest big change.
|
|
</li>
|
|
<li>Collision resistance: Can not find 2 input produce same digest.</li>
|
|
</ul>
|
|
<h2>
|
|
<a
|
|
id="user-content-mac-aka-message-authentication-code-produce-from-key-message-to-authentication-tag"
|
|
class="anchor"
|
|
aria-hidden="true"
|
|
tabindex="-1"
|
|
href="#mac-aka-message-authentication-code-produce-from-key-message-to-authentication-tag"
|
|
><span aria-hidden="true" class="octicon octicon-link"></span
|
|
></a>
|
|
<strong>MAC</strong> aka Message Authentication Code produce from key,
|
|
message to authentication tag.
|
|
</h2>
|
|
<ul>
|
|
<li>A send B message with MAC (generate from message and A key).</li>
|
|
<li>
|
|
B double check message with MAC (generate from receive message and B
|
|
key).
|
|
</li>
|
|
<li>A and B use same key.</li>
|
|
</ul>
|
|
<div class="highlight highlight-source-mermaid">
|
|
<pre><span class="pl-k">sequenceDiagram</span>
|
|
<span class="pl-k">participant</span> <span class="pl-ent">alice</span>
|
|
<span class="pl-k">participant</span> <span class="pl-ent">bob</span>
|
|
|
|
<span class="pl-ent">alice </span><span class="pl-k">->></span> <span class="pl-ent">bob</span><span class="pl-k">:</span> <span class="pl-s">send alice, mac(secret_key_alice, alice)</span>
|
|
<span class="pl-ent">bob </span><span class="pl-k">->></span> <span class="pl-ent">bob</span><span class="pl-k">:</span> <span class="pl-s">compare mac(secret_key_alice, alice) with mac(secret_key_bob, alice)</span></pre>
|
|
</div>
|
|
<ul>
|
|
<li>
|
|
Prevent forgery: without secret_key, can not generate MAC even if
|
|
knowing <strong>a lot of</strong> alice and mac(secret_key, alice),
|
|
</li>
|
|
<li>Prevent collisions: keep MAC long enough (256-bit),</li>
|
|
<li>
|
|
Replay attacks: send transaction 2 times with perfectly MAC and u know
|
|
why -> instead of mac(secret_key, alice), use
|
|
<strong>counter</strong> as mac(secret_key, counter, alice).
|
|
</li>
|
|
<li>
|
|
Verify must be done in <strong>constant time</strong>: if not, probaly
|
|
return error the moment the bytes differ -> attacker recreate byte by
|
|
byte by measuring how long -> timing attacks
|
|
</li>
|
|
</ul>
|
|
<p>Constant time comparision:</p>
|
|
<div class="highlight highlight-source-go">
|
|
<pre><span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">:=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1"><</span> <span class="pl-en">len</span>(<span class="pl-s1">x</span>); <span class="pl-s1">i</span><span class="pl-c1">++</span> {
|
|
<span class="pl-c">// Use XOR instead of compare x[i] == y[i]</span>
|
|
<span class="pl-c">// If x[i] == y[i] -> XOR is 1</span>
|
|
<span class="pl-c">// Otherwise XOR is 0</span>
|
|
<span class="pl-s1">v</span> <span class="pl-c1">|=</span> <span class="pl-s1">x</span>[<span class="pl-s1">i</span>] <span class="pl-c1">^</span> <span class="pl-s1">y</span>[<span class="pl-s1">i</span>]
|
|
}
|
|
|
|
<span class="pl-c">// v == 1 means all XOR is 1 means x == y</span></pre>
|
|
</div>
|
|
<p>Use for:</p>
|
|
<ul>
|
|
<li>
|
|
Integrity: because MAC ensure no one can tamper with message without
|
|
noticing
|
|
</li>
|
|
</ul>
|
|
<div class="highlight highlight-source-mermaid">
|
|
<pre><span class="pl-k">sequenceDiagram</span>
|
|
<span class="pl-k">participant</span> <span class="pl-ent">alice</span>
|
|
<span class="pl-k">participant</span> <span class="pl-ent">bob</span>
|
|
|
|
<span class="pl-ent">alice </span><span class="pl-k">->></span> <span class="pl-ent">bob</span><span class="pl-k">:</span> <span class="pl-s">send username, password</span>
|
|
<span class="pl-ent">bob </span><span class="pl-k">-->></span> <span class="pl-ent">alice</span><span class="pl-k">:</span> <span class="pl-s">return alice|mac(secret_key, alice)</span>
|
|
<span class="pl-ent">alice </span><span class="pl-k">->></span> <span class="pl-ent">bob</span><span class="pl-k">:</span> <span class="pl-s">send alice|mac(secret_key, alice)</span>
|
|
<span class="pl-ent">bob </span><span class="pl-k">-->></span> <span class="pl-ent">alice</span><span class="pl-k">:</span> <span class="pl-s">return OK</span>
|
|
<span class="pl-ent">alice </span><span class="pl-k">->></span> <span class="pl-ent">bob</span><span class="pl-k">:</span> <span class="pl-s">send bob|mac(secret_key, alice)</span>
|
|
<span class="pl-ent">bob </span><span class="pl-k">-->></span> <span class="pl-ent">alice</span><span class="pl-k">:</span> <span class="pl-s">return ERROR</span></pre>
|
|
</div>
|
|
<p><strong>HMAC</strong> is MAC using hash</p>
|
|
<h2>
|
|
<a
|
|
id="user-content-aes-advanced-encryption-standard"
|
|
class="anchor"
|
|
aria-hidden="true"
|
|
tabindex="-1"
|
|
href="#aes-advanced-encryption-standard"
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
>AES (Advanced Encryption Standard)
|
|
</h2>
|
|
<p>
|
|
Currently (2023) the world using AES-128 which take a key 128 bits == 16
|
|
bytes
|
|
</p>
|
|
<ul>
|
|
<li>Take a variable-length key</li>
|
|
<li>Take plaintext of 128 bits</li>
|
|
<li>Give ciphertext of 128 bits</li>
|
|
</ul>
|
|
<p>
|
|
AES is kind of cipher, handle fixed-size plaintext so we called
|
|
<strong>block cipher</strong>. AES is deterministic so we can encrypt and
|
|
decrypt.
|
|
</p>
|
|
<h2>
|
|
<a
|
|
id="user-content-aes-cbc-cipher-block-chaining"
|
|
class="anchor"
|
|
aria-hidden="true"
|
|
tabindex="-1"
|
|
href="#aes-cbc-cipher-block-chaining"
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
>AES-CBC (Cipher Block Chaining)
|
|
</h2>
|
|
<p>
|
|
What if text you want to encrypt longer than 128 bytes ? We add
|
|
<strong>padding</strong> for text to become multi block which has 128
|
|
bytes, then encrypt each block.
|
|
</p>
|
|
<p>
|
|
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 ?
|
|
</p>
|
|
<p>
|
|
Just use <strong>PKCS#7 padding</strong>. 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 <code>07</code>.
|
|
</p>
|
|
<div class="highlight highlight-text-adblock">
|
|
<pre>XX XX XX XX XX XX XX XX XX 07 07 07 07 07 07 07</pre>
|
|
</div>
|
|
<p>
|
|
So to know how much padding bytes should we remove -> read last bytes
|
|
(<code>07</code>) to know the length to remove trailing padding bytes.
|
|
</p>
|
|
<p>
|
|
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 (ECB penguin).
|
|
</p>
|
|
<p>CBC = deterministic block cipher + IV (initialization vector)</p>
|
|
<p>AES-CBC encrypt:</p>
|
|
<ul>
|
|
<li>
|
|
IV XOR first plaintext -> AES encrypt -> first ciphertext.
|
|
ciphertext.
|
|
</li>
|
|
<li>Use first ciphertext as IV to second ciphertext and so on.</li>
|
|
</ul>
|
|
<p>AES-CBC decrypt:</p>
|
|
<ul>
|
|
<li>AES decrypt first ciphertext -> XOR IV -> first plaintext.</li>
|
|
<li>Use first ciphertext as IV to second block and so on.</li>
|
|
</ul>
|
|
<p>Because IV, same plaintext can encrypt to different ciphertext.</p>
|
|
<p>
|
|
<strong>WARNING</strong> If IV become predictable, AES-CBC become
|
|
deterministic -> BEAST attack (Browser Exploit Against SSL/TLS).
|
|
</p>
|
|
<h2>
|
|
<a
|
|
id="user-content-aead-authenticated-encryption-with-associated-data"
|
|
class="anchor"
|
|
aria-hidden="true"
|
|
tabindex="-1"
|
|
href="#aead-authenticated-encryption-with-associated-data"
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
>AEAD (Authenticated Encryption with Associated Data)
|
|
</h2>
|
|
<p>
|
|
Because AES-CBC requires IV which shows public -> attacker can change
|
|
IV -> lack of authenticity -> use AES-CBC-HMAC or AEAD.
|
|
</p>
|
|
<p>AEAD provides a way to authenticate <strong>associated data</strong>.</p>
|
|
<h2>
|
|
<a
|
|
id="user-content-aes-gcm-galoiscounter-mode-aead"
|
|
class="anchor"
|
|
aria-hidden="true"
|
|
tabindex="-1"
|
|
href="#aes-gcm-galoiscounter-mode-aead"
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
>AES-GCM (Galois/Counter Mode) AEAD
|
|
</h2>
|
|
<p>AES-GCM = AES-CTR (Counter) + GMAC message authentication code</p>
|
|
<p>AES-CTR encrypt:</p>
|
|
<ul>
|
|
<li>Create nonce 12 bytes (same purpose as IV).</li>
|
|
<li>Concatenate nonce with counter 4 bytes: 1, 2, 3, ...</li>
|
|
<li>
|
|
Encrypt AES from concatenated none with counter to
|
|
<strong>keystream</strong>.
|
|
</li>
|
|
<li>XOR keystream with plaintext -> ciphertext.</li>
|
|
</ul>
|
|
<p>
|
|
Limit is counter only up to 4 bytes so only handle plaintext of 2^32 - 1
|
|
blocks of 16 bytes aka 69 GBs.
|
|
</p>
|
|
<p>
|
|
AES-CTR no need padding because if keystream is longer than plaintext, it
|
|
is truncated to plaintext length before XOR.
|
|
</p>
|
|
<p>This is stream cipher, differ from block cipher.</p>
|
|
<p>GMAC is MAC with GHASH. GHASH resembles CBC mode.</p>
|
|
<h2>
|
|
<a
|
|
id="user-content-chacha20-poly1305-aed"
|
|
class="anchor"
|
|
aria-hidden="true"
|
|
tabindex="-1"
|
|
href="#chacha20-poly1305-aed"
|
|
><span aria-hidden="true" class="octicon octicon-link"></span></a
|
|
>ChaCha20-Poly1305 AED
|
|
</h2>
|
|
<p>ChaCha20-Poly1305 = ChaCha20 stream cipher + Poly1305 MAC</p>
|
|
|
|
<div>
|
|
Feel free to ask me via
|
|
<a href="mailto:hauvipapro+posts@gmail.com">email</a> or
|
|
<a rel="me" href="https://hachyderm.io/@haunguyen">Mastodon</a>.
|
|
<br />Source code is available on
|
|
<a href="https://github.com/haunt98/posts-go">GitHub</a>
|
|
<a href="https://codeberg.org/yoshie/posts-go">Codeberg</a>
|
|
<a href="https://git.sr.ht/~youngyoshie/posts-go">sourcehut</a>
|
|
<a href="https://gitea.treehouse.systems/yoshie/posts-go">Treehouse</a>
|
|
<a href="https://gitlab.com/youngyoshie/posts-go">GitLab</a>
|
|
</div>
|
|
</body>
|
|
</html>
|