def dh_encrypt(pub, message, aliceSig=None): """ Assume you know the public key of someone else (Bob), and wish to Encrypt a message for them. - Generate a fresh DH key for this message. - Derive a fresh shared key. - Use the shared key to AES_GCM encrypt the message. - Optionally: sign the message with Alice's key. """ ## YOUR CODE HERE # Bob's public key is a point on the curve bob_pub = pub G, alice_priv, alice_pub = dh_get_key() # Alice's private key is a scalar # shared_key_point = bob_pub * alice_priv # this is multiplication of a point with a scalar shared_key_point = bob_pub.pt_mul(alice_priv) # We convert this shared_key point to a # string binary representation with .export # # .export : # "Returns a string binary representation # of the point in compressed coordinates" shared_key_point_binary = shared_key_point.export() # Then we hash the value to produce a 256 bit key shared_key = sha256(shared_key_point_binary).digest() plaintext = message.encode("utf8") ## YOUR CODE HERE aes = Cipher("aes-256-gcm") iv = urandom(16) encrypted_text, tag = aes.quick_gcm_enc(shared_key, iv, plaintext) # iv, encrypted_text, tag = encrypt_message(shared_key, message) return alice_pub, iv, encrypted_text, tag
def __init__(self, G, name, priv, pki): # Maths self.G = G self.g = self.G.generator() self.order = self.G.order() ## Store keys self.priv = priv self.pub = priv * self.g self.pki = pki self.name = name # Which channel are we in? self.admins = [] self.members = [] # Channel key stores self.Ks = [] ## Generate an ephemeral signature key self.priv_sign = self.order.random() self.pub_sign = self.priv_sign * self.g ## Storage for short term dictionaries self.current_dict = {"me": self.pub_sign} ## Generate an ephemeral signature key self.priv_enc = self.order.random() self.pub_enc = self.priv_enc * self.g self.aes = Cipher("aes-128-gcm")
def dh_encrypt(pub, message, aliceSig = None): """ Assume you know the public key of someone else (Bob), and wish to Encrypt a message for them. - Generate a fresh DH key for this message. - Derive a fresh shared key. - Use the shared key to AES_GCM encrypt the message. - Optionally: sign the message with Alice's key. """ # pub is bob's pub key, alicesig is my private sig key, # which shuold be different from enc/dec keypair # for cryptographic sec reasons # priv is an integer, pub is an ec point alice_G, alice_priv, alice_pub = dh_get_key() # shared secret = my priv x bob's pub point shared_key = alice_priv * pub # hash ec pt to derive key shared_key = sha256(shared_key.export()).digest() # aes_gcm encrypt aes = Cipher("aes-256-gcm") iv = urandom(len(shared_key)) ciphertext, tag = aes.quick_gcm_enc(shared_key, iv, message.encode("utf-8")) # sign message (assume using common curve) # hash ciphertext sig = do_ecdsa_sign(EcGroup(), aliceSig, sha256(ciphertext).digest()) if aliceSig else None # return alice_pub for dh_decrypt on bob side # (because bob needs alice's pub to gen shared secret) return (iv, ciphertext, tag, alice_pub, sig)
def dh_decrypt(priv, ciphertext, aliceVer = None): """ Decrypt a received message encrypted using your public key, of which the private key is provided. Optionally verify the message came from Alice using her verification key.""" # ciphertext be (iv, ciphertext, tag, sender_pub, sig) # bob decrypting: check sig using alice's pub ver key, # then decrypt using shared key derived from priv (bob's private key) # check input parameter format if (not isinstance(ciphertext, tuple)) or (isinstance(ciphertext, tuple) and len(ciphertext) != 5): raise Exception("Expecting tuple (iv, ciphertext, tag, sender public key, signature).") iv, encmsg, tag, sender_pub, sig = ciphertext # verify signature if aliceVer: if not sig: raise Exception("Signature required before decyption.") elif not do_ecdsa_verify(EcGroup(), aliceVer, sig, sha256(encmsg).digest()): raise Exception("Signature verification failed.") # shared key = bob priv x alice's pub point shared_key = priv * sender_pub # hash shared_key = sha256(shared_key.export()).digest() # decrypt aes = Cipher("aes-256-gcm") plaintext = aes.quick_gcm_dec(shared_key, iv, encmsg, tag) return plaintext.encode("utf-8")
def __init__(self, group=None, header_len = 192, body_len = 1024, assoc_len=0, k=16, dest_len=16): self.aes = Cipher("AES-128-CTR") self.cbc = Cipher("AES-128-CBC") self.assoc_len = assoc_len self.max_len = header_len self.zero_pad = b"\x00" * (2 * self.max_len) self.m = body_len self.k = k self.dest_len = dest_len self.group = group if not group: self.group = Group_ECC()
def aes_enc_dec(self, data): ''' AES Enc/Dec ''' aes = Cipher("AES-128-CBC") enc = aes.enc(self.key, self.ctr_iv) output = enc.update(data) output += enc.finalize() return output
def dh_encrypt(pub, message): """ Assume you know the public key of someone else (Bob), and wish to Encrypt a message for them. - Generate a fresh DH key for this message. - Derive a fresh shared key. - Use the shared key to AES_GCM encrypt the message. - Optionally: sign the message. """ Group, private, public = dh_get_key() #generate new DH pair for Alice #private key is an integer/scalar and public key is a point on the curve #check whether public key of Bob is valid and on curve assert Group.check_point(pub) #Alice obtains shared secret by multiplying her private key with bob's forwarded public key key = pub.pt_mul(private) #dA* qB print "key from enc is", key hashedKey = sha256(key.export()).digest() plaintext = message.encode("utf8") #encode message aes = Cipher("aes-128-gcm") #select cipher iv = urandom(16) #generate initialization vector cipher, tag = aes.quick_gcm_enc(hashedKey[:16], iv, plaintext) #encrypt using shared key ciphertext = [iv, cipher, tag, public] return ciphertext
class PublicParams(object): ec_group = attrib(default=Factory(EcGroup)) hash_func = attrib(default=Factory(lambda: sha256)) enc_cipher = attrib(default=Factory(lambda: Cipher("aes-128-gcm"))) enc_key_size = attrib(default=16) lookup_key_size = attrib(default=8) nonce_size = attrib(default=16)
def test_cbc_oram_enc_dec(): aes = Cipher("AES-128-CBC") key = urandom(16) iv = urandom(16) ipt = [urandom(16), "Hello"] IV, data = ipt IV0 = KDF(iv, IV).iv enc = aes.enc(key, IV0) data = enc.update(data) data += enc.finalize() IV1 = KDF(iv, data[0:16]).iv enc = aes.enc(key, IV1) IV = enc.update(IV) IV += enc.finalize() datablock = [IV, data] IV, data = datablock IV1 = KDF(iv, data[0:16]).iv dec = aes.dec(key, IV1) IV = dec.update(IV) IV += dec.finalize() IV0 = KDF(iv, IV).iv dec = aes.dec(key, IV0) data = dec.update(data) data += dec.finalize() datablock = [IV, data] assert ipt == datablock
def aes_enc_dec(self, key, iv, input_): """A helper function which implements the AES-128 encryption in counter mode CTR""" aes = Cipher("AES-128-CTR") enc = aes.enc(key, iv) output = enc.update(input_) output += enc.finalize() return output
def encrypt_message(K, message): """ Encrypt a message under a key K """ plaintext = message.encode("utf8") aes = Cipher("aes-128-gcm") iv = urandom(16) ciphertext, tag = aes.quick_gcm_enc(K, iv, plaintext) return (iv, ciphertext, tag)
def aes_cbc(self, key, IV, data): #Input: Encryption key, Initialization vector, data to encrypt #Output: Encrypted data with IV and key aes = Cipher("AES-128-CBC") enc = aes.enc(key, IV) output = enc.update(data) output += enc.finalize() return output
def encrypt_message(K, message, key_length=16): """ Encrypt a message under a key K """ plaintext = message.encode("utf8") aes = Cipher("aes-{}-gcm".format(key_length * 8)) iv = urandom(key_length) ciphertext, tag = aes.quick_gcm_enc(K, iv, plaintext) return iv, ciphertext, tag
def decrypt_message(K, iv, ciphertext, tag): """ Decrypt a cipher text under a key K In case the decryption fails, throw an exception. """ aes = Cipher("aes-128-gcm") plain = aes.quick_gcm_dec(K, iv, ciphertext, tag) return plain.encode("utf8")
def decrypt_message(K, iv, ciphertext, tag, key_length=16): """ Decrypt a cipher text under a key K In case the decryption fails, throw an exception. """ aes = Cipher("aes-{}-gcm".format(key_length * 8)) plain = aes.quick_gcm_dec(K, iv, ciphertext, tag) return plain.encode("utf8")
def decrypt_message(K, iv, ciphertext, tag): """ Decrypt a cipher text under a key K In case the decryption fails, throw an exception. """ ## YOUR CODE HERE aes = Cipher("aes-128-gcm") # Initialize AES-GCM with 128 bit keys plain = aes.quick_gcm_dec(K, iv, ciphertext, tag) return plain.encode("utf8")
def encrypt_message(K, message): """ Encrypt a message under a key K """ ## YOUR CODE HERE plaintext = message.encode("utf8") aes = Cipher("aes-128-gcm") # Initialize AES-GCM with 128 bit keys iv = urandom(16) # Encryption using AES-GCM returns a ciphertext and a tag ciphertext, tag = aes.quick_gcm_enc(K, iv, plaintext) return (iv, ciphertext, tag)
def dh_decrypt(priv, ciphertext, aliceVer=None): """ Decrypt a received message encrypted using your public key, of which the private key is provided. Optionally verify the message came from Alice using her verification key.""" iv, enc_msg, tag, pub_enc = ciphertext shared_key = pub_enc.pt_mul(priv).export() hashed_shared_key = sha256(shared_key).digest() aes = Cipher("aes-128-gcm") plaintext = aes.quick_gcm_dec(hashed_shared_key[:16], iv, enc_msg, tag).encode("utf-8") return plaintext
def dh_decrypt(priv, ciphertext, aliceVer=None): """ Decrypt a received message encrypted using your public key, of which the private key is provided. Optionally verify the message came from Alice using her verification key.""" ## YOUR CODE HERE iv, ciphertext, tag, pub_enc = ciphertext freshKey = pub_enc.pt_mul(priv).export()[:16] aes = Cipher("aes-128-gcm") plaintext = aes.quick_gcm_dec(freshKey, iv, ciphertext, tag) return plaintext.encode("utf8")
def decrypt_message(K, iv, ciphertext, tag): """ Decrypt a cipher text under a key K In case the decryption fails, throw an exception. """ ## YOUR CODE HERE try: aes = Cipher("aes-128-gcm") plain = aes.quick_gcm_dec(K, iv, ciphertext, tag) except: raise Exception("decryption failed") return plain.encode("utf8")
def decrypt_message(K, iv, ciphertext, tag): """ Decrypt a cipher text under a key K In case the decryption fails, throw an exception. """ ## YOUR CODE HERE # we declare the aes cipher aes = Cipher("aes-128-gcm") # we decode the ciphertext plain = aes.quick_gcm_dec(K, iv, ciphertext, tag) # we return the unencrypted message return plain.encode("utf8")
def decrypt_message(K, iv, ciphertext, tag): """ Decrypt a cipher text under a key K In case the decryption fails, throw an exception. """ ## YOUR CODE HERE tests aes = Cipher("aes-128-gcm") try: m = aes.quick_gcm_dec(K, iv, ciphertext,tag) m = m.decode("utf8") except: raise Exception('decryption failed') return m
def aes_ctr_enc_dec(key, iv, input): """ A helper function that implements AES Counter (CTR) Mode encryption and decryption. Expects a key (16 byte), and IV (16 bytes) and an input plaintext / ciphertext. If it is not obvious convince yourself that CTR encryption and decryption are in fact the same operations. """ aes = Cipher("AES-128-CTR") enc = aes.enc(key, iv) output = enc.update(input) output += enc.finalize() return output
def decrypt_message(K, iv, ciphertext, tag, key_length=128): """ Decrypt a cipher text under a key K In case the decryption fails, throw an exception. """ if key_length not in [128, 192, 256]: raise Exception("Invalid key length") aes = Cipher("aes-%s-gcm" % str(key_length)) plain = aes.quick_gcm_dec(K, iv, ciphertext, tag) return plain.encode("utf8")
def decrypt_message(K, iv, ciphertext, tag): """ Decrypt a cipher text under a key K In case the decryption fails, throw an exception. """ plain = '' aes = Cipher("aes-128-gcm") try: plain = aes.quick_gcm_dec(K, iv, ciphertext,tag) plain = plain.decode("utf8") except: raise Exception('decryption failed') return plain
def encrypt_message(K, message): """ Encrypt a message under a key K """ plaintext = message.encode("utf8") ## YOUR CODE HERE # we declare the aes cipher aes = Cipher("aes-128-gcm") # we generate the iv iv = urandom(16) # we encrypt the message "plaintext" using the key K provided and the iv we generated ciphertext, tag = aes.quick_gcm_enc(K, iv, plaintext) return (iv, ciphertext, tag)
def encrypt_message(K, message, key_length=128): """ Encrypt a message under a key K """ plaintext = message.encode("utf8") iv = urandom(16) if key_length not in [128, 192, 256]: raise Exception("Invalid key length") aes = Cipher("aes-%s-gcm" % str(key_length)) ciphertext, tag = aes.quick_gcm_enc(K, iv, plaintext) return (iv, ciphertext, tag)
def dh_encrypt(pub, message, aliceSig=None): """ Assume you know the public key of someone else (Bob), and wish to Encrypt a message for them. - Generate a fresh DH key for this message. - Derive a fresh shared key. - Use the shared key to AES_GCM encrypt the message. - Optionally: sign the message with Alice's key. """ (G, priv_dec, pub_enc) = dh_get_key() shared_key = pub.pt_mul(priv_dec).export() hashed_shared_key = sha256(shared_key).digest() iv = urandom(16) aes = Cipher("aes-128-gcm") ciphertext, tag = aes.quick_gcm_enc(hashed_shared_key[:16], iv, message.encode("utf-8")) return (iv, ciphertext, tag, pub_enc)
def test_cbc_enc_dec(): aes = Cipher("AES-128-CBC") key = urandom(16) iv = urandom(16) ipt = "Hello" enc = aes.enc(key, iv) ciphertext = enc.update(ipt) ciphertext += enc.finalize() dec = aes.dec(key, iv) plaintext = dec.update(ciphertext) plaintext += dec.finalize() assert ipt == plaintext
def cascade_rebuild(self, seed, key, iv, flags, inverse, data): #Cascade Rebuild data processing function #print "MIX: Cascade Rebuild enc/perm" if not inverse and not flags[2]: data = self.permute(seed, data, inverse) aes = Cipher("AES-128-CTR") enc = aes.enc(key, iv) #for i in range(len(data)): # data[i] = enc.update(data[i]) # data[i] += enc.finalize() if inverse and not flags[2]: data = self.permute(seed, data, inverse) return data