def round1_setup_packages_decode(pkgs, crypto, chksum_test=True): # Break apart the received setup package packet per the above method # and return the unencrypted data along with the cryptographic box # to perform this again plaintext, hash_pkgs, h_target = None, -1, -2 box = None pkg_data,hash_data = [], [] chksum = pkgs[0:64] if chksum_test and (not chksum == sha256(pkgs[64:])): raise Exception("Checksum does not match") cert_hex = pkgs[64:128] path_length = int(pkgs[128:130]) pkg_size = int(pkgs[130:134]) hash_size = int(pkgs[134:138]) # Create a box box = crypto.public_box(PrivateKey(cert_hex, encoder=nacl.encoding.HexEncoder)) # Now get the packages and hashes hash_start = 138+(path_length*pkg_size) for i in range(path_length): pkg_i = pkgs[138+(i*pkg_size):138+((i+1)*pkg_size)] hash_i = pkgs[hash_start+(i*hash_size):hash_start+((i+1)*hash_size)] pkg_data.append(pkg_i) hash_data.append(hash_i) # Attempt to decrypt the packages (and calculate the hash on other # encrypted packages) and decrypt the hashes one by one i = 0 for pkg in pkg_data: try: plaintext = box.decrypt(pkg) s = None if i == path_length - 1: s = ''.join(pkg_data[0:i]) else: s = ''.join(pkg_data[0:i]+pkg_data[i+1:path_length]) h_target = sha256(s) break except: pass i += 1 for h in hash_data: try: hash_pkgs = box.decrypt(h) break except: pass if hash_pkgs == h_target: return box, plaintext else: raise Exception("Hashes do not match")
def init(prefs, the_ephemeral_key, has=False): encrypted_prefs = [] for pref in prefs: if not has: hashed_reciprocal_pref = sha256(reciprocal_map[pref]) want_pref = c.crypto_scalarmult(the_ephemeral_key, hashed_reciprocal_pref) encrypted_prefs.append(want_pref) else: hashed_pref = sha256(pref) have_pref = c.crypto_scalarmult(the_ephemeral_key, hashed_pref) encrypted_prefs.append(have_pref) return encrypted_prefs
def decrypt_message(encrypted_message, keying_material, private_key): encrypted_key = keying_material['encrypted_key'] message_signature = keying_material['message_signature'] temp_public_key = PublicKey( keying_material['temp_public_key'], Base64Encoder) box = PublicBox(private_key, temp_public_key) message_key = box.decrypt( encrypted_key, encoder=Base64Encoder) # We got the key, so let's get the message. message_box = nacl.secret.SecretBox(message_key) message = message_box.decrypt( encrypted_message, encoder=Base64Encoder) # Check the signature. mac_key = sha256(box._shared_key, RawEncoder) signing_key = SigningKey(mac_key) if signing_key.sign(message, Base64Encoder) != message_signature: raise SignatureError("The signature is not valid") return message
def create_key(self, key_id=None): key = random(SecretBox.KEY_SIZE) if not key_id: h = sha256(key, HexEncoder) key_id = h.decode('utf-8')[:16] self.keys[key_id] = key log_debug("Key {} was created.".format(key_id)) self.save_key(key_id) return key_id
def key_test( msg='test', key_enc='pbb6wrDXlLWOFMXYH4a9YHh7nGGD1VnStVYQBe9MyVU=' ): from hashlib import sha256 key = key_generate() assert key_sign_check(key_get_vk(key), msg, key_sign(key, msg)) key = key_decode_sk(key_enc) key_vk = key_get_vk(key) sign = key_sign(key, msg) assert key_sign_check(key_vk, msg, sign) print(sha256(''.join([ key_encode(key), key_encode(key_vk), key_encode(key_decode_vk(key_encode(key_vk))), key_get_id(key), key_get_id(key_vk), msg, sign ])).hexdigest())
def round1_setup_package(self): # To generate an output string we use the struct module that converts # the data into a c-style btye str/array # See: http://docs.python.org/2/library/struct.html s = pack("<15s15sH64s32s32s64s64sBB", \ self.prev_ip_addr, \ self.next_ip_addr, \ self.next_port, \ self.path_construction_cert_hex, \ self.prev_id, \ self.next_id, \ self.prev_path_building_cert_hex, \ self.next_path_building_cert_hex, \ self.type, \ self.terminating, \ ) s += pack("<64s", sha256(s)) # append the hash of the decrypted package # TODO: Pack seeds and tuples return s
def encrypt_message(message, identifier): """Encrypts a message so that it can be read by all the devices of the given identifier. :param message: the message itself, in clear text. :param identifier: the identifier of the message recipient. """ # Cipher the message with a brand new random key. message_key = nacl.utils.random(nacl.secret.SecretBox.KEY_SIZE) message_box = nacl.secret.SecretBox(message_key) message_nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE) encrypted_message = message_box.encrypt(message, message_nonce, Base64Encoder) returned = [] # Encrypt the message key with each recipient's public key. for recipient_device_pub_key in get_public_keys(identifier): # Generate a new keypair & cipher the key with it. temp_private_key, temp_public_key = generate_keypair() box = PublicBox(temp_private_key, recipient_device_pub_key) nonce = nacl.utils.random(PublicBox.NONCE_SIZE) encrypted_key = box.encrypt(message_key, nonce, Base64Encoder) # Sign the message. mac_key = sha256(box._shared_key, RawEncoder) signing_key = SigningKey(mac_key) message_sig = signing_key.sign(message, Base64Encoder) # Return the public key used to cipher the message key. returned.append({ 'encrypted_key': encrypted_key, 'temp_public_key': temp_public_key.encode(Base64Encoder), 'message_signature': message_sig }) return { 'encrypted_message': encrypted_message, 'recipients': returned }
def hash_(data): return sha256(data).decode('hex')
def key_get_id(key): if isinstance(key, SigningKey): key = key.verify_key return '{{:>{}s}}'.format(key_id_len).format( sha256(key.encode(), URLSafeBase64Encoder)[:key_id_len] )
def round1_setup_packages(self): # Generate a bunch of setup package data (strings) pkgs_and_nodes = [] for node in self.nodes[1:-1]: pkg = node.round1_setup_package() pkg_encrypted = node.box.encryptn(pkg) # pkg_encrypted = node.encrypt_and_sign(pkg, self.path_construction_key) pkgs_and_nodes.append( (node, pkg_encrypted)) # append the node so we know the proper crypto keys # Shuffle the order of the setup packages shuffle(pkgs_and_nodes) pkgs = [x[1] for x in pkgs_and_nodes] # separate out pkgs # compute hash on (array - package) for each package (and shuffle) hashes = [] for i in range(len(pkgs_and_nodes)): node = pkgs_and_nodes[i][0] s = None if i == len(pkgs) - 1: s = ''.join(pkgs[0:i]) else: s = ''.join(pkgs[0:i]+pkgs[i+1:]) h = node.box.encryptn(sha256(s)) hashes.append(h) shuffle(hashes) # Format: # 0) 64 byte transmission checksum # 1) 64 byte cert (hex) # 2) 2 byte path length (N) # 3) 4 byte package length (X) # 4) 4 byte hash length (Y) # 5) N packages of length X # 6) N packages of length Y # 1) pkg_str = self.my_node.path_building_cert_hex # 2) s = str(self.length) while len(s) < 2: s = '0' + s pkg_str += s # 3) s = str(len(pkgs[0])) while len(s) < 4: s = '0' + s pkg_str += s # 4) s = str(len(hashes[0])) while len(s) < 4: s = '0' + s pkg_str += s # 5 and 6) for pkg in pkgs: pkg_str += pkg for h in hashes: pkg_str += h # 0) out = sha256(pkg_str) + pkg_str return out