def test_api(self): self.assertTrue('aes' in cipher.names, 'no AES') key = b'0123456789abcdef' iv = b'0' * 16 msg = b'hello, world' enc = cipher.aes(key, iv).encrypt(msg) self.assertEqual(cipher.aes(key, iv).decrypt(enc), msg)
def incoming(self, wrapper, payload, address): """Hands off incoming packets to appropriate Lines""" t, iv = wrapper['type'], wrapper['iv'].decode('hex') if t == 'line': l = wrapper['line'] if l in self.lines: self.lines[l].recv(iv, payload) elif t == 'open': remote_ecc_key = self.local.decrypt(wrapper['open']) aes_key = sha256(remote_ecc_key) body = aes(aes_key.digest(), iv).decrypt(payload) inner, remote_rsa = packet.decode(body) remote = SwitchID(key=remote_rsa) hn = remote.hash_name log.debug('Received open from %s' % hn) remote_line = inner['line'].decode('hex') aes_key.update(remote_line) candidate_line = self.known_hashes.get(hn, None) encrypted_sig = wrapper['sig'].decode('base64') sig = aes(aes_key.digest(), iv).decrypt(encrypted_sig) secrets = (remote_line, remote_ecc_key) if not remote.verify(sha256(payload).digest(), sig): log.debug('Invalid signature from: %s' % hn) return if candidate_line is not None: log.debug('Open for existing Line: %s' % candidate_line) line = self.lines[candidate_line] if line.secret is None: line.ecdh(secrets) else: line = Line(self.local, self.sendto, address, remote, secrets) self.lines[line.id] = line self.known_hashes[hn] = line.id else: pass # Fwomp
def _open(self, local, remote, secrets=None): inner = { 'to': remote.hash_name, 'at': int(time.time() * 1000), 'line': self.id } body = packet.encode(inner, local.pub_key_der) self._ecc_key = ecc.Key(256) ecc_key_pub = self._ecc_key.public.as_string(format='der', ansi=True) aes_key = sha256(ecc_key_pub) iv = os.urandom(16) encrypted_body = aes(aes_key.digest(), iv).encrypt(body) sig = local.sign(sha256(encrypted_body).digest()) aes_key.update(self._id) encrypted_sig = aes(aes_key.digest(), iv).encrypt(sig) outer = { 'type': 'open', 'open': remote.encrypt(ecc_key_pub), 'iv': iv.encode('hex'), 'sig': encrypted_sig.encode('base64').translate(None, '\n') } log.debug('Sending open to: %s' % remote.hash_name) if secrets is not None: self.ecdh(secrets) self.sendto(packet.encode(outer, encrypted_body), self.remote_iface)
def _send_open(self): iv = os.urandom(16) aes_key = sha256(self._ecc_pub) enc_body = aes(aes_key.digest(), iv).encrypt(self._open) aes_key.update(self.line.id.decode('hex')) sig = self.local_id.sign(sha256(enc_body).digest()) enc_sig = aes(aes_key.digest(), iv).encrypt(sig) o = self.id.encrypt(self._ecc_pub) data = packet.wrap_open(o, iv, enc_sig, enc_body) self._send(data) log.debug('Open to: %s' % self.id.hash_name) log.debug('Line: %s to %s' % (self.line.id, self.line.rid))
def send(self, data, body=''): iv = os.urandom(16) log.debug('Sending on Line %s:' % self.id) log.debug(data) payload = packet.encode(data, body) enc_payload = aes(self.aes_enc, iv).encrypt(payload) return packet.wrap_line(self.rid, iv, enc_payload)
def test_iv_requirements(self): zero = b'\0' * 16 nonzero = b'0123456789abcdef' # ECC x = cipher.aes(nonzero, mode='ecb') y = cipher.aes(nonzero, None, 'ecb') self.assertRaises(ValueError, cipher.aes, nonzero, zero, 'ecb') self.assertRaises(ValueError, cipher.aes, nonzero, nonzero, 'ecb') # Not ECC self.assertRaises(ValueError, cipher.aes, nonzero, mode='ctr') self.assertRaises(ValueError, cipher.aes, nonzero, None, 'ctr') x = cipher.aes(nonzero, zero, 'ctr') y = cipher.aes(nonzero, nonzero, 'ctr')
def read_open(me, sender_ecc, wrapper, payload): aes_key = sha256(sender_ecc) sig_test = sha256(payload).digest() iv = wrapper['iv'].decode('hex') body = aes(aes_key.digest(), iv).decrypt(payload) inner, sender_rsa = packet.decode(body) remote = SwitchID(key=sender_rsa) if not all(k in inner for k in ('to', 'at', 'line')): raise PacketException('Malformed inner open') enc_sig = wrapper['sig'].decode('base64') line_id = inner['line'].decode('hex') aes_key.update(line_id) sig = aes(aes_key.digest(), iv).decrypt(enc_sig) if not remote.verify(sig_test, sig): raise PacketException('Invalid signature in open') if inner['to'] != me: raise PacketException('Open addressed to wrong hash_name?!') #TODO: validate these too return remote, line_id, inner['at']
def recv(self, iv, pkt): data, body = packet.decode(aes(self.aes_dec, iv).decrypt(pkt)) c = data['c'] t = data.get('type', None) candidate_channel = self.channels.get(c, None) if candidate_channel is not None: candidate_channel.incoming(data, body) if t is not None: channel = Channel(c, data, body) self.channels[c] = channel
def recv(self, iv, pkt): data, body = packet.decode(aes(self.aes_dec, iv).decrypt(pkt)) return data, body
def test_api(self): self.assertTrue("aes" in cipher.names, "no AES") key = b"0123456789abcdef" msg = b"hello, world" enc = cipher.aes(key).encrypt(msg) self.assertEqual(cipher.aes(key).decrypt(enc), msg)
def test_iv_getset(self): nonzero = b'0123456789abcdef' x = cipher.aes(nonzero, None, 'ecb') self.assertRaises(ValueError, x.get_iv) self.assertRaises(ValueError, x.set_iv, nonzero)
r = len_data % 16 for i in range(16 - r): data += '0' return convertir_16_bytes(data) key = input('Ingrese una llave para encriptar: ') key = convertir_16_bytes(key, is_key=True) key = bytes(key, 'utf-8') message = input('Ingrese un mensaje para encriptar: ') message = convertir_16_bytes(message, is_key=True) message = bytes(message, 'utf-8') my_cipher = cipher.aes(key, b'\0' * 16, mode='eax', nonce=b'random', header=b'a header') cifrado = my_cipher.encrypt(message) print(cifrado) my_cipher.done() my_cipher = cipher.aes(key, b'\0' * 16, mode='eax', nonce=b'random', header=b'a header') print(my_cipher.decrypt(cifrado)) my_cipher.done()
def test_convience_args(self): # Args should be: key, iv, mode. nonzero = b'0123456789abcdef' z = cipher.aes(nonzero, nonzero, 'cbc')
def test_bytearrays(self): key = b'0123456789abcdef' iv = b'0' * 16 msg = bytearray(b'hello, world') enc = cipher.aes(key, iv).encrypt(msg) self.assertEqual(cipher.aes(key, iv).decrypt(enc), msg)
# TODO: refactor into packet encoding function # --------------- # defaults to utf-8 inner_open_json = json.dumps(inner_open, separators=(',', ':'), sort_keys=True) inner_len = len(inner_open_json) id_key_len = len(id_key_pub) # magical C string packing fmt_str = '!H' + str(inner_len) + 's' + str(id_key_len) + 's' inner_open_packet = pack(fmt_str, inner_len, inner_open_json, id_key_pub) # --------------- hasher = hash.new('sha256', session_ecc_pub) sym_key = cipher.aes(key=hasher.digest(), iv=iv, mode='ctr') outer_body = sym_key.encrypt(inner_open_packet) outer_open = {} outer_open['type'] = 'open' outer_open['open'] = dest_key.encrypt(session_ecc_pub) \ .encode('base64').translate(None, '\n') outer_open['iv'] = iv.encode('hex') hasher.update(line_id) sym_key = cipher.aes(key=hasher.digest(), iv=iv, mode='ctr') """ The current version of PyTomCrypt won't hash the message before signing so we need to do this manually, but the underlying libTomCrypt still needs to know which hashing algorithm was used to sign properly. """
def test_memoryviews(self): key = b'0123456789abcdef' iv = b'0' * 16 msg = memoryview(b'hello, world') enc = cipher.aes(key, iv).encrypt(msg) self.assertEqual(cipher.aes(key, iv).decrypt(enc), msg)