mirror of
https://github.com/20kaushik02/CSE539_Applied_Cryptography_Midterm.git
synced 2025-12-06 06:14:08 +00:00
Initial commit
Completed DH-AES part yesterday
This commit is contained in:
commit
c6ecfa305b
BIN
DH-AES/DH-AES-Project.pdf
Normal file
BIN
DH-AES/DH-AES-Project.pdf
Normal file
Binary file not shown.
33
DH-AES/README.md
Normal file
33
DH-AES/README.md
Normal file
@ -0,0 +1,33 @@
|
||||
# Diffie-Hellman and AES encryption
|
||||
|
||||
## Setup and requirements
|
||||
|
||||
- Recommended Python version: 3.10.5 or later
|
||||
- Install packages from requirements.txt
|
||||
|
||||
## Run program
|
||||
|
||||
The specified example's inputs:
|
||||
|
||||
```shell
|
||||
python3 dh_aes.py "A2 2D 93 61 7F DC 0D 8E C6 3E A7 74 51 1B 24 B2" 251 465 255 1311 2101864342 8995936589171851885163650660432521853327227178155593274584417851704581358902 "F2 2C 95 FC 6B 98 BE 40 AE AD 9C 07 20 3B B3 9F F8 2F 6D 2D 69 D6 5D 40 0A 75 45 80 45 F2 DE C8 6E C0 FF 33 A4 97 8A AF 4A CD 6E 50 86 AA 3E DF" AfYw7Z6RzU9ZaGUloPhH3QpfA1AXWxnCGAXAwk3f6MoTx
|
||||
```
|
||||
|
||||
This gives the attached outputs:
|
||||

|
||||
|
||||
For a more verbose output, include the `--verbose` flag:
|
||||
|
||||
```shell
|
||||
python3 dh_aes.py "A2 2D 93 61 7F DC 0D 8E C6 3E A7 74 51 1B 24 B2" 251 465 255 1311 2101864342 8995936589171851885163650660432521853327227178155593274584417851704581358902 "F2 2C 95 FC 6B 98 BE 40 AE AD 9C 07 20 3B B3 9F F8 2F 6D 2D 69 D6 5D 40 0A 75 45 80 45 F2 DE C8 6E C0 FF 33 A4 97 8A AF 4A CD 6E 50 86 AA 3E DF" AfYw7Z6RzU9ZaGUloPhH3QpfA1AXWxnCGAXAwk3f6MoTx --verbose
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Notes and inferences
|
||||
|
||||
- Recent versions (2.2+) of Python automatically handle large numbers
|
||||
- Little-endian vs big-endian: given inputs are little-endian byte arrays, so when converting keys from integers to bytes, we convert to little-endian byte order
|
||||
- `cryptography` package is used here for AES - `pip install cryptography`
|
||||
- Used AES-256 algorithm - CBC mode of operation, using provided initialization vector (IV is commonly prepended to ciphertext in practice)
|
||||
- [Library reference for implementation](https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#cryptography.hazmat.primitives.ciphers.Cipher)
|
||||
102
DH-AES/dh_aes.py
Normal file
102
DH-AES/dh_aes.py
Normal file
@ -0,0 +1,102 @@
|
||||
import os
|
||||
import argparse
|
||||
|
||||
from cryptography.hazmat.primitives import padding
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
|
||||
|
||||
def prettyBytes(bytestr: bytes) -> str:
|
||||
"""Prints byte strings like `\\x3d\\xe9\\xb7` as `3D E9 B7`"""
|
||||
return " ".join([bytestr[i : i + 1].hex().upper() for i in range(0, len(bytestr))])
|
||||
|
||||
|
||||
def buildExpNum(exponent: int, constant: int, base: int = 2) -> int:
|
||||
return pow(base, exponent) - constant
|
||||
|
||||
|
||||
def calculateSharedKey(
|
||||
g_e: int, g_c: int, N_e: int, N_c: int, x: int, gy_modN: int
|
||||
) -> int:
|
||||
"""Diffie-Hellman shared key computation (single-party)"""
|
||||
# g = build_exp_num(g_e, g_c) # not needed since gy_modN is given
|
||||
N = buildExpNum(N_e, N_c)
|
||||
return pow(gy_modN, x, N)
|
||||
|
||||
|
||||
def encrypt(plaintext: bytes, key: int, iv: bytearray) -> bytes:
|
||||
"""Encryption using AES-256 in CBC mode"""
|
||||
key_byte_length = 32
|
||||
cipher = Cipher(
|
||||
algorithms.AES(key.to_bytes(key_byte_length, byteorder="little")), modes.CBC(iv)
|
||||
)
|
||||
|
||||
padder = padding.PKCS7(algorithms.AES.block_size).padder()
|
||||
padded_plaintext = padder.update(plaintext) + padder.finalize()
|
||||
|
||||
encryptor = cipher.encryptor()
|
||||
return encryptor.update(padded_plaintext) + encryptor.finalize()
|
||||
|
||||
|
||||
def decrypt(ciphertext: bytes, key: int, iv: bytearray) -> bytes:
|
||||
"""Decryption using AES-256 in CBC mode"""
|
||||
key_byte_length = 32
|
||||
cipher = Cipher(
|
||||
algorithms.AES(key.to_bytes(key_byte_length, byteorder="little")), modes.CBC(iv)
|
||||
)
|
||||
|
||||
decryptor = cipher.decryptor()
|
||||
return decryptor.update(ciphertext) + decryptor.finalize()
|
||||
|
||||
|
||||
def main(args: argparse.Namespace) -> None:
|
||||
# pre-processing inputs
|
||||
iv = bytearray.fromhex(args.initialization_vector)
|
||||
g_e = int(args.g_e)
|
||||
g_c = int(args.g_c)
|
||||
N_e = int(args.N_e)
|
||||
N_c = int(args.N_c)
|
||||
x = int(args.x)
|
||||
gy_modN = int(args.gy_modN)
|
||||
ciphertext = bytearray.fromhex(args.ciphertext)
|
||||
plaintext = str.encode(args.plaintext, "utf-8")
|
||||
verbose = args.verbose
|
||||
|
||||
shared_key = calculateSharedKey(g_e, g_c, N_e, N_c, x, gy_modN)
|
||||
if verbose:
|
||||
print(("-" * os.get_terminal_size().columns) + "\n")
|
||||
print("Shared key\t\t", shared_key)
|
||||
print(("-" * os.get_terminal_size().columns) + "\n")
|
||||
|
||||
new_pt = decrypt(ciphertext, shared_key, iv)
|
||||
if verbose:
|
||||
print("Given ciphertext\t", prettyBytes(ciphertext))
|
||||
print("Calculated plaintext\t", new_pt.decode("utf-8"))
|
||||
print(("-" * os.get_terminal_size().columns) + "\n")
|
||||
|
||||
new_ct = encrypt(plaintext, shared_key, iv)
|
||||
if verbose:
|
||||
print("Given plaintext\t\t", args.plaintext)
|
||||
print("Calculated ciphertext\t", prettyBytes(new_ct))
|
||||
print(("-" * os.get_terminal_size().columns) + "\n")
|
||||
|
||||
if not verbose:
|
||||
print(f"{new_pt.decode('utf-8')}, {prettyBytes(new_ct)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="DHKE keygen and AES encryption/decryption"
|
||||
)
|
||||
parser.add_argument("initialization_vector", help="")
|
||||
parser.add_argument("g_e", help="Exponent (base 2), for g")
|
||||
parser.add_argument("g_c", help="Constant to be subtracted, for g")
|
||||
parser.add_argument("N_e", help="Exponent (base 2), for N")
|
||||
parser.add_argument("N_c", help="Constant to be subtracted, for N")
|
||||
parser.add_argument("x", help="Alice's private key value")
|
||||
parser.add_argument("gy_modN", help="g^y modulo N, computed by Bob")
|
||||
parser.add_argument("ciphertext", help="Ciphertext to be decrypted")
|
||||
parser.add_argument("plaintext", help="Plaintext to be encrypted")
|
||||
parser.add_argument("-v", "--verbose", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
BIN
DH-AES/dh_aes_output.png
Normal file
BIN
DH-AES/dh_aes_output.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
DH-AES/dh_aes_verbose_output.png
Normal file
BIN
DH-AES/dh_aes_verbose_output.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
1
DH-AES/requirements.txt
Normal file
1
DH-AES/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
cryptography==41.0.5
|
||||
Loading…
x
Reference in New Issue
Block a user