Private Key Encryption Scheme
In the private key encryption scheme:
- The same key is used for encryption and decryption.
- This key should be kept private against the adversary.
- The private key must be securely shared before performing encryption and
decryption.
Threat model
Passive attack: The adversary can simply perform eavesdropping the communication
channel.
Known plaintext attack: The adversary has some plaintext-ciphertext
pairs.
Chosen plaintext attack: The adversary has a control over which
plaintext to be encrypte. (Example: World War II). In theory, we model an
adversary who has encryption capability (even without knowing the key).
Chosen ciphertext attack: In an ultimately serious scenario, the
adversary may additionally obtain some power of accessing the information
about the decrypted message (Example: padding oracle attack). In theory, the
attacker is modeled to have both encryption AND decryption capability
(without knowing the key).
| |
Security notion: indistinguishability (under a chosen plaintext attack)
The security definition considers a mental experiment.
Think of this mental experiment as a kind of
car crash test to assess how
secure and robust a car is.
Although this experiment is designed to
capture security concerns regarding real scenarios,
but it's not really the same as any specific
real scenario.
- Give the adversary time to inspect the encryption scheme.
- Let the adversary choose two plaintexts that will be most easily
crackable from his perspective. (This step captures the chosen plaintext
attack).
- Pick one of the two messages at random and encrypt it.
- Give the resulting ciphertext to the adversary.
- Have the adversary guess which message has been encrypted.
- The ciphertext reveals nothing about the plaintext, the adversary can be
successfully only by random guessing, which is exactly probability 1/2.
To capture this (relaxing it only slightly), if the probability that
the adversary makes the good guess is 1/2 + negligible, then the encryption
scheme is called indistinguishable. Here, negligible is
something like 1/10000000000000.
|
|
Block ciphers
A block cipher works on fixed-length blocks. The most famous block cipher is
AES.
Spciefically, A block cipehr \(F\) is a deterministic algorithm that works as follows:
- Input: \( K, M \)
- \(K\): A fixed-length encryption key
- \(M\): A fixed-length plaintext block.
- Output: \(C\)
- \(C\): A fixed-length ciphertext block.
Requirement
- The length of M is fixed, and it's the same as the
length of C.
- We call the length of M (= the length of C) as the block size.
We use the following notation:
\[ C \leftarrow F_K(M) \]
Block cipher = Pseudorandom permutation
A block cipher is also called a pseudorandom permutation. In
particular, a cipher block looks random, if you don't know the key (and even if
you know the message block).
| |
Decryption
If you have a key, then block cipher allows you to decrypt a ciphertext.
Mode of Operations: Encrypting a long message
Electronic Code Book (ECB) Mode
|
The encryption scheme with ECB mode is not indistinguishable under chosen
plaintext attack.
| |
Cipher Block Chaining (CBC) Mode
|
|
If IV is chosen uniformly random, the encryption scheme with CBC mode is
indistinguishable under a chosen plaintext attack.
It is important to choose IV randomly. Otherwise, for example, if the same
message is encrypted again in some future, the adversary will note it.
|
Counter (CTR) Mode
|
|
If ctr is chosen uniformly random, the encryption scheme with CTR mode is
indistinguishable under a chosen plaintext attack.
It is important to choose IV randomly. Otherwise, for example, if the same
message is encrypted again in some future, the adversary will note it.
|
Comparison
| | padding | IV or ctr | randomized encryption | parallel
encryption | parallel decryption | security
|
| ECB
| yes | no | no | yes | yes | no
|
| CBC
| yes | yes | yes | no | yes | yes with random IV
|
| CTR
| no | yes | yes | yes | yes | yes with random ctr
|
Message Authentication Code (MAC)
A MAC scheme provides message integrity. A MAC consists of three algorithms
\( ({\sf MGen}, {\sf Mac}, {\sf MVer}) \) shown in
the following picture.
- Again, the same key $K$ is used for both ${\sf MAC}$ and ${\sf MVer}$.

Using MAC to ensure message
integerity
Security: unforgeability
We call that a MAC scheme is unforgeable if no adversary should be able to
generate a valid MAC tag on any new message.
Secure MAC scheme: HMAC
Let \( H: \{0,1\}^* \rightarrow \{0,1\}^n \) be a
collision resistant hash function.
The idea for the construction is that the tag should be something like
the hash on both the key and the message. Since the adversary doesn't know
the key, it will probably have hard time in guessing the right hash
value on (key, message). However, simply computing $H( K || M )$ is known
to be insecure, and the construction uses the "double-layer" hashing.

HMAC with SHA-256 hash function
Using Python
Writing the experiment of indistinguishability under a chosen ciphertext
attack
Do you remember this experiment and how to break it?
$ ./part7.py
The target ciphertext is
iv: 81109c7dff291f6c57f0d6479a334ac8
ct: c892dfdcdaead56d88fbfebac7142442c0fdc499ff0694983d4cd251afd32fb0da6595f66d3e5fb091b7a0f0f18ad9b5
=============
Menu: 0 (encrypt), 1 (decrypt), 2 (open): 0
msg to encrypt in a hexstring format: 11223344aabb
iv: a681a0c60ae6fab05f9f1762d3de9ed5
ct: 36be519e0bf9a9fe84e3d51323925195
=============
Menu: 0 (encrypt), 1 (decrypt), 2 (open): 1
iv (in hexstring): a681a0c60ae6fab05f9f1762d3de9ed5
ct (in hexstring): 36be519e0bf9a9fe84e3d51323925195
decryption is:
b'\x11"3D\xaa\xbb'
=============
Menu: 0 (encrypt), 1 (decrypt), 2 (open): 1
iv (in hexstring): 81109c7dff291f6c57f0d6479a334ac8
ct (in hexstring): c892dfdcdaead56d88fbfebac7142442c0fdc499ff0694983d4cd251afd32fb0da6595f66d3e5fb091b7a0f0f18ad9b5
Cannot decrypt the target ciphertext!
=============
Menu: 0 (encrypt), 1 (decrypt), 2 (open): 1
iv (in hexstring): a7bdcc39485abc97f1e20e372e08bfa1
ct (in hexstring): 1216c53c503147f45eb6e970a90ba959
decryption is:
b'Hello World'
=============
Menu: 0 (encrypt), 1 (decrypt), 2 (open): 2
The message was: b"Don't use ECB. It's not IND-CPA secure"
Using HMAC in Python
Write code lab08.py that implements the following function:
def computeHMAC(key, data):
- In the above, both
key and data are
bytes objects.
- Use SHA-256 as the underlying hash function.
- Refer to the
hmac documentation.
Sample run with pic_original.bmp.
>>> import lab08
>>> key = b"0123456789abcdef"
>>> data = open("pic_original.bmp", "rb").read()
>>> lab08.computeHMAC(key, data)
b'c2\xba$\x93@\xa4\x9d\xe2\x07\x065`\xb0\xe5$\xb6F\xd5\xact>\x02\xf88r\xc1\x81\x04\xf3\xa45'
>>> key = b"my really secret key"
>>> lab08.computeHMAC(key, data)
b'G]\x90\xb5\xd2:@s\xc3y\x1b\xed\x8a\x9d+$\xbe\r\x9b\x14g\xed \x06\x0c\x813%d\x889F'
Pickle
The pickle module
implements serializing and de-serializing a Python object.
- Pickling: a Python object → a bytes object (or binary file)
- Unpickling: The inverse procedure.
Bytes → Object: Unpickling with pickle.loads()
We can dump a Python object to a bytes stream using pickle.dumps() function.
We can load a Python object from a bytes object using pickle.loads() function.
>>> x = {1:"hello", "list":[1,2,3], "key": 100}
>>> type(x)
<class 'dict'>
>>> import pickle
>>> b = pickle.dumps(x)
>>> b
b'\x80\x04\x95(\x00\x00\x00\x00\x00\x00\x00}\x94(K\x01\x8c\x05hello\x94\x8c\x04list\x94]\x94(K\x01K\x02K\x03e\x8c\x03key\x94Kdu.'
>>> y = pickle.loads(b)
>>> y
{1: 'hello', 'list': [1, 2, 3], 'key': 100}
>>>
Warning
It is possible to construct malicious pickle data which will execute arbitrary
code during unpickling. Never unpickle data that could have come from an
untrusted source, or that could have been tampered with.
Safer serialization formats such as json may be more appropriate if you are
processing untrusted data.
Json
Pickle dumps an object in a binary format. Using json
module, you can dump an object into a string format.
- However, you cannot serialize a custom-made class. You can only serialize
the standard objects such as list, dictionary, number and strings.
- As with
pickle, you can use dumps, loads, dump,
load functions.
>>> x = {1:"hello", "list":[1,2,3], "key": 100}
>>> type(x)
<class 'dict'>
>>> import json
>>> s = json.dumps(x)
>>> s
'{"1": "hello", "list": [1, 2, 3], "key": 100}'
>>> type(s)
<class 'str'>
>>> y = json.loads(s)
>>> y
{'1': 'hello', 'list': [1, 2, 3], 'key': 100}