def encrypt_with_public_key(self, key, data): """ info: Encrypts data with public key. :param key: bytes or ras key object :param data: bytes :return: bytes: encrypted data """ if not isinstance(key, bytes): public_key = key else: public_key = serialization.load_pem_public_key(key, backend=default_backend()) # setup aes aes_raw_key = aead.AESGCM.generate_key(bit_length=self._aes_key_size) aes_key = aead.AESGCM(aes_raw_key) nonce = os.urandom(self._nonce_key_size) # get random data size random_data_size = self._random.randint(0, self._max_random) raw_random_data_size = random_data_size.to_bytes(length=self._random_header_size, byteorder="big", signed=False) # AES encrypt data [random header][random data][data] data = raw_random_data_size + os.urandom(random_data_size) + data encrypted_data = aes_key.encrypt(nonce, data, self._authenticator) # RSA encrypt [AES key][nonce][sandy check key] rsa_header = aes_raw_key + nonce + Encryption.make_sandy_check_key(data) encrypted_rsa_header = public_key.encrypt(rsa_header, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) return encrypted_rsa_header + encrypted_data
def Encrypt(stream: IO[bytes], key: bytes) -> IO[bytes]: """Encrypts given file-like object using AES algorithm with GCM mode. The input stream is divided into small chunks of predefined size and then each chunk is encrypted using AES GCM procedure. In the encoded stream, before each proper chunk there is a nonce binary string prepended. As associated data for each encrypted chunk, chunk index and information about whether it is the last chunk is used. Args: stream: A file-like object to encrypt. key: A secret key used for encrypting the data. Returns: A file-like object with encrypted data. """ aesgcm = aead.AESGCM(key) def Generate() -> Iterator[bytes]: chunks = ioutil.Chunk(stream, size=_AEAD_CHUNK_SIZE) chunks = iterator.Lookahead(enumerate(chunks)) for idx, chunk in chunks: nonce = os.urandom(_AEAD_NONCE_SIZE) adata = _AEAD_ADATA_FORMAT.pack(idx, chunks.done) yield nonce + aesgcm.encrypt(nonce, chunk, adata) return ioutil.Unchunk(Generate())
def TestInput(input_bytes): if len(input_bytes) < 12: return fdp = atheris.FuzzedDataProvider(input_bytes) choice = fdp.ConsumeIntInRange(1, 4) if choice == 1: cipher = aead.ChaCha20Poly1305(aead.ChaCha20Poly1305.generate_key()) if choice == 2: cipher = aead.AESGCM(aead.AESGCM.generate_key(bit_length=128)) if choice == 3: cipher = aead.AESOCB3(aead.AESOCB3.generate_key(bit_length=128)) if choice == 4: cipher = aead.AESCCM(aead.AESCCM.generate_key(bit_length=128)) msg = fdp.ConsumeBytes(32) authentext = fdp.ConsumeBytes(32) nonce = fdp.ConsumeBytes(12) if len(nonce) < 12: return ciphertext = cipher.encrypt(nonce, msg, authentext) plaintext = cipher.decrypt(nonce, ciphertext, authentext) assert (plaintext == msg), "Encryption/Decrption error!"
def encrypt(self, plain_text, aad=None): plain_text = ensure_binary(plain_text) try: iv = get_random_bytes(algorithms.AES.block_size // 8) mode = self._mode(iv) if mode.name == "GCM": cipher = aead.AESGCM(self._key) cipher_text_and_tag = cipher.encrypt(iv, plain_text, aad) cipher_text = cipher_text_and_tag[:len(cipher_text_and_tag) - 16] auth_tag = cipher_text_and_tag[-16:] else: cipher = Cipher(algorithms.AES(self._key), mode, backend=default_backend()) encryptor = cipher.encryptor() padder = PKCS7(algorithms.AES.block_size).padder() padded_data = padder.update(plain_text) padded_data += padder.finalize() cipher_text = encryptor.update( padded_data) + encryptor.finalize() auth_tag = None return iv, cipher_text, auth_tag except Exception as e: raise JWEError(e)
def decrypt(self, cipher_text, iv=None, aad=None, tag=None): cipher_text = six.ensure_binary(cipher_text) try: iv = six.ensure_binary(iv) mode = self._mode(iv) if mode.name == "GCM": if tag is None: raise ValueError("tag cannot be None") cipher = aead.AESGCM(self._key) cipher_text_and_tag = cipher_text + tag try: plain_text = cipher.decrypt(iv, cipher_text_and_tag, aad) except InvalidTag: raise JWEError("Invalid JWE Auth Tag") else: cipher = Cipher(algorithms.AES(self._key), mode, backend=default_backend()) decryptor = cipher.decryptor() padded_plain_text = decryptor.update(cipher_text) padded_plain_text += decryptor.finalize() unpadder = PKCS7(algorithms.AES.block_size).unpadder() plain_text = unpadder.update(padded_plain_text) plain_text += unpadder.finalize() return plain_text except Exception as e: raise JWEError(e)
def get_aead_cipher(key, method): '''get_aead_cipher method should be AEAD method''' if method.startswith('aes'): return aead.AESGCM(key) try: return aead.ChaCha20Poly1305(key) except Exception: from .ctypes_libsodium import SodiumAeadCrypto return SodiumAeadCrypto(method, key)
def testIncorrectTag(self): key = os.urandom(32) aesgcm = crypto_aead.AESGCM(key) buf = io.BytesIO() nonce = os.urandom(aead._AEAD_NONCE_SIZE) buf.write(nonce) buf.write(aesgcm.encrypt(nonce, b"foo", b"QUUX")) buf.seek(0, io.SEEK_SET) with self.assertRaises(crypto_exceptions.InvalidTag): aead.Decrypt(buf, key).read()
def testIncorrectData(self): key = os.urandom(32) aesgcm = crypto_aead.AESGCM(key) buf = io.BytesIO() nonce = os.urandom(aead._AEAD_NONCE_SIZE) adata = aead._AEAD_ADATA_FORMAT.pack(0, True) buf.write(nonce) buf.write(aesgcm.encrypt(nonce, b"foo", adata)) buf.getbuffer()[-1] ^= 0b10101010 # Corrupt last byte. buf.seek(0, io.SEEK_SET) with self.assertRaises(crypto_exceptions.InvalidTag): aead.Decrypt(buf, key).read()
def salvar(self, evt): dados_para_salvar = self.__tipoAlteracaoEscolhida dados_para_salvar += ":" + self.__formulaHashOuCriptoEscolhida if self.__tipoAlteracaoEscolhida in self.__tiposAlteracoes: if self.__tipoAlteracaoEscolhida == 'Criptografia': dados_para_salvar += ":" + self._txtChave.GetValue() dados_para_salvar += ":" + self._txtIV.GetValue() dados_para_salvar += ":" + self._txtEntradaDados.GetValue() elif self.__tipoAlteracaoEscolhida == 'Hmac': dados_para_salvar += ":" + self._txtChave.GetValue() dados_para_salvar += ":" + self._txtEntradaDados.GetValue() dialogNome = wx.TextEntryDialog( self, _('Escolha um nome para o conjunto de dados de criptografia:'), caption=_('Salvar Configurações de Criptografia')) dialogNome.ShowModal() dialogSenha = wx.TextEntryDialog( self, _('Entre uma senha para criptografar essas configurações, ela será necessária ' 'para carregar essas informações mais tarde:'), caption=_('Salvar configurações de Criptografia')) dialogSenha.ShowModal() nome = dialogNome.GetValue() senha = dialogSenha.GetValue() iteracoes = 1000000 if senha is not '' or None: salt = os.urandom(32) senha = senha.encode() dados_para_salvar = dados_para_salvar.encode() chave = PBKDF2HMAC(algorithm=hashes.SHA3_256, length=32, salt=salt, iterations=1000000, backend=default_backend()).derive(senha) nounce = os.urandom(16) aesgcm = aead.AESGCM(chave) dados_criptografados = aesgcm.encrypt(nounce, dados_para_salvar, None) dados_para_salvar = salt + dados_criptografados + nounce ts = datetime.now() arquivo = shelve.open('cyfer') arquivo[nome] = { "data": ts, 'iterações': iteracoes, 'dados': dados_para_salvar } arquivo.close()
def Decrypt(stream: IO[bytes], key: bytes) -> IO[bytes]: """Decrypts given file-like object using AES algorithm in GCM mode. Refer to the encryption documentation to learn about the details of the format that this function allows to decode. Args: stream: A file-like object to decrypt. key: A secret key used for decrypting the data. Returns: A file-like object with decrypted data. """ aesgcm = aead.AESGCM(key) def Generate() -> Iterator[bytes]: # Buffered reader should accept `IO[bytes]` but for now it accepts only # `RawIOBase` (which is a concrete base class for all I/O implementations). reader = io.BufferedReader(stream) # pytype: disable=wrong-arg-types # We abort early if there is no data in the stream. Otherwise we would try # to read nonce and fail. if not reader.peek(): return for idx in itertools.count(): nonce = reader.read(_AEAD_NONCE_SIZE) # As long there is some data in the buffer (and there should be because of # the initial check) there should be a fixed-size nonce prepended to each # chunk. if len(nonce) != _AEAD_NONCE_SIZE: raise EOFError(f"Incorrect nonce length: {len(nonce)}") chunk = reader.read(_AEAD_CHUNK_SIZE + 16) # `BufferedReader#peek` will return non-empty byte string if there is more # data available in the stream. is_last = reader.peek() == b"" # pylint: disable=g-explicit-bool-comparison adata = _AEAD_ADATA_FORMAT.pack(idx, is_last) yield aesgcm.decrypt(nonce, chunk, adata) if is_last: break return ioutil.Unchunk(Generate())
def tentar_abrir_arq_config(self, nome): try: arq = shelve.open('cyfer') dados = arq[nome]['dados'] arq.close() salt = dados[:32] nounce = dados[-16:] dados = dados[32:len(dados) - 16] dialogSenha = wx.TextEntryDialog( self, _('Entre a senha para decriptografar essas configurações:'), caption=_('Carregar configurações de Criptografia')) dialogSenha.ShowModal() senha = dialogSenha.GetValue().encode() chave = PBKDF2HMAC(algorithm=hashes.SHA3_256, length=32, salt=salt, iterations=1000000, backend=default_backend()).derive(senha) dados_decriptografados = aead.AESGCM(chave).decrypt( nounce, dados, None) dados_separados = dados_decriptografados.decode().split(':') if dados_separados[0] == 'Criptografia': self.comboBoxTipoAlteracao.SetSelection(0) self.eventoComboBoxTipoAlteracao(None) self.comboBoxFormulaHashOuCripto.SetSelection( self._Criptografia_para_escolher.index(dados_separados[1])) self.eventoComboBoxFormulaHashOuCripto(None) self._txtChave.Clear() self._txtChave.WriteText(dados_separados[2]) self._txtIV.Clear() self._txtIV.WriteText(dados_separados[3]) self._txtEntradaDados.Clear() self._txtEntradaDados.WriteText(dados_separados[4]) elif dados_separados[0] == 'Hmac': self.comboBoxTipoAlteracao.SetSelection(2) self.eventoComboBoxTipoAlteracao(None) self.comboBoxFormulaHashOuCripto.SetSelection( self._Hmac_para_escolher.index(dados_separados[1])) self.eventoComboBoxFormulaHashOuCripto(None) self._txtChave.Clear() self._txtChave.WriteText(dados_separados[2]) self._txtEntradaDados.Clear() self._txtEntradaDados.WriteText(dados_separados[3]) except KeyError: self.error_dialog( _('Não há nenhum arquivo com esse nome que possua configurações para esse programa.' ))
def decrypt(self, data): """ info: Decrypt message. The data will also be checked for corruption. :param data: bytes :return: bytes: Unencrypted data. """ try: # decrypt rsa block rsa_block = self._private_key.decrypt(data[:self._rsa_block_size], padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) # get aes key aes_raw_key = rsa_block[:-(self._nonce_key_size + self._sha_block_size)] # get nonce nonce = rsa_block[-(self._nonce_key_size + self._sha_block_size):-self._sha_block_size] # get sandy check key sandy_check_key = rsa_block[-self._sha_block_size:] # make aes decrypter aes_key = aead.AESGCM(aes_raw_key) # get aes encrypted data data = data[self._rsa_block_size:] # get unencrypted ase data data = aes_key.decrypt(nonce, data, self._authenticator) # sandy check data if not Encryption.check_sandy_check_key(sandy_check_key, data): raise EncryptionError("Sandy Check Failed") # remove random bytes random_data_size = int.from_bytes(data[:self._random_header_size], byteorder="big", signed=False) return data[random_data_size + self._random_header_size:] except Exception as e: raise EncryptionError("Cant decrypt: {0}".format(e))
def _decrypt_report_id(guid): """Decrypt and verify the report id. Returns ------- str or None Decrypted id if successfully decrypted, None otherwise. """ config = get_config() key = base64.b64decode(config.get(CONF_SECTION, CONF_KEY_KEY)) # https://cryptography.io/en/latest/hazmat/primitives/aead/ aes_gcm = aead.AESGCM(key) try: encoded_nonce, encoded_data = guid.split(',', 1) nonce = base64.b64decode(encoded_nonce) encypted_data = base64.b64decode(encoded_data) return aes_gcm.decrypt(nonce, encypted_data, None) except (ValueError, TypeError, InvalidTag): print('Invalid guid given to resolveReport:', guid, file=sys.stderr) return None
def main(): data = sys.stdin.read().encode() key = aead.AESGCM.generate_key(bit_length=256) aesgcm = aead.AESGCM(key) nonce = os.urandom(12) ct = aesgcm.encrypt(nonce, data, b'') data = { "nonce": base64.b64encode(nonce).decode(), "ct": base64.b64encode(ct).decode(), "key": "", } for key_id, credential_id, public_key in iter_keys(): print("Encrypt for %s" % key_id) kct = public_key.encrypt( key, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) data["key"] = base64.b64encode(kct).decode() with open("database/%s" % credential_id.replace("/", "_"), "w") as out: out.write(json.dumps(data))
def on_message(client, userdata, msg): global name global mode global asymmetric_mode global symmetric_mode global b_public_key global b_public_key_ecdh global a_shared_key global f_key global a_key global h global hmac_key print(msg.topic + " -> " + str(msg.payload.decode())) # Connection message if (msg.topic == "connection"): print("Connection message.") # Initialize some variables name = str(msg.payload.decode()).split(":")[0] mode = str(msg.payload.decode()).split(":")[1] asymmetric_mode = int(str(msg.payload.decode()).split(":")[2]) symmetric_mode = int(str(msg.payload.decode()).split(":")[3]) # Save the variables for each device names.append(name) modes.append(mode) asymmetric_modes.append(asymmetric_mode) symmetric_modes.append(symmetric_mode) # Key exchange if (asymmetric_mode == 0): client.publish(name + "/to", "param:" + str(params_pem, 'ascii')) client.publish(name + "/to", "public:" + str(a_public_key.public_numbers().y)) else: client.publish( name + "/to", "public:" + a_public_key_ecdh.public_bytes( encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo).decode()) client.subscribe(name + "/from") print("Public key sent to device.") # Show the information on web page data = { "type": "conexion_dispositivo", "payload": msg.payload.decode() } server.send_message_to_all(json.dumps(data)) # Message from a device that has already connected else: # Topic = <Device name>/from name = str(msg.topic).split("/")[0] if (msg.topic == (name + "/from")): # Receive device public key if (str(msg.payload.decode()).split(":")[0] == "public"): # If we know its old public key, we upload it try: public_keys.pop(names.index(name)) shared_keys.pop(names.index(name)) fernet_keys.pop(names.index(name)) aead_keys.pop(names.index(name)) print("Public key uploaded from device.") # If we don't know its public key, we save it except IndexError: # If the device has 'output' or nothing if (int(mode) > 0): # HMAC key will be introduced on web page data = {"type": "hmac", "name": name, "mode": mode} # If the device has just 'input' else: # HMAC key will be introduced on device hmac_key = str(os.urandom(2).hex()) data = { "type": "hmac", "name": name, "mode": mode, "hmac_key": hmac_key } # Show the correspondent information on web page server.send_message_to_all(json.dumps(data)) print("New public key from device.") # DH key exchange if (asymmetric_modes[names.index(name)] == 0): b_public_key_number = int( str(msg.payload.decode()).split(":")[1]) peer_public_numbers = dh.DHPublicNumbers( b_public_key_number, parameters.parameter_numbers()) b_public_key = peer_public_numbers.public_key( default_backend()) public_keys.insert(names.index(name), b_public_key) a_shared_key = a_private_key.exchange(b_public_key) # ECDH key exchange else: b_public_key_number = str( msg.payload.decode()).split(":")[1] b_public_key_ecdh = load_pem_public_key( b_public_key_number.encode()) a_shared_key = a_private_key_ecdh.exchange( ec.ECDH(), b_public_key_ecdh) print("Shared key calculated.") # Save the shared key shared_keys.insert(names.index(name), a_shared_key) # We fix the shared key for Fernet using HASH and save it derived_key_fernet = HKDF( algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data').derive(a_shared_key) key_fernet = base64.urlsafe_b64encode(derived_key_fernet) f_key = Fernet(key_fernet) fernet_keys.insert(names.index(name), f_key) # We fix the shared key for AEAD using HASH and save it derived_key_aead = HKDF( algorithm=hashes.SHA256(), length=24, salt=None, info=b'handshake data').derive(a_shared_key) key_aead = base64.urlsafe_b64encode(derived_key_aead) a_key = aead.AESGCM(key_aead) aead_keys.insert(names.index(name), a_key) # Receive HMAC from device elif (str(msg.payload.decode()).split(":")[0] == "hmac"): # Save received HMAC print("HMAC recibida del dispositivo.") h = str(msg.payload.decode()).split(":")[1] # If the device has just 'input' if (int(mode) == 0): # DH or ECDH if (asymmetric_mode == 0): h2 = hmac.new( bytes(hmac_key, 'ascii'), bytes(str(b_public_key.public_numbers().y), 'ascii'), hashlib.sha256) else: h2 = hmac.new( bytes(hmac_key, 'ascii'), b_public_key_ecdh.public_bytes( encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo), hashlib.sha256) # Compare HMAC if (hmac.compare_digest(h, h2.hexdigest())): hmacs.append(True) data = { "type": "datos_dispositivos", "name": name, "mode": mode } # Device will be added on web page if HMAC is correct server.send_message_to_all(json.dumps(data)) print("HMAC de " + name + " coincide. Añadiendo dispositivo...") else: hmacs.append(False) # Unsubscribe client.unsubscribe(name + "/from") print("HMAC de " + name + " no coincide. Dispositivo expulsado.") # Receive message from device elif (str(msg.payload.decode()).split(": ")[0] == "message"): message = str(msg.payload.decode()).split(": ")[1] # Fernet or AEAD if (symmetric_modes[names.index(name)] == 0): message = fernet_keys[names.index(name)].decrypt( message.encode()) else: message = aead_keys[names.index(name)].decrypt( b"12345678", message.encode('latin-1'), None) print("Message from " + name + ": " + message.decode()) # Show the correspondent information on web page data = { "type": "message", "name": name, "payload": message.decode() } # model data server.send_message_to_all(json.dumps(data))
# prompt for input on stderr def einput(text): sys.stderr.write(text) return input() # getpass and encode passwd = lambda prompt='Enter Password: '******'utf-8') # split string at index split = lambda string, index: (string[:index], string[index:]) # get aead cipher depending on arguments aead = lambda key, cipher: AEAD.AESGCM(key) if cipher == Aenker.cipher_t.Value( 'AESGCM') else AEAD.ChaCha20Poly1305(key) # key derivation wrappers class KDF: argon2 = lambda password, blob :\ split(argon2_raw(password, blob.nonce, \ blob.kdf_opts.time_cost, 2**blob.kdf_opts.memory_cost, blob.kdf_opts.parallelism, \ hash_len=44, type=argon2_type.I), 12) # parse commandline arguments argparser = argparse.ArgumentParser()
def __init__(self, key): assert len(key) * 8 == self.KEY_BITS self._cipher = aead.AESGCM(key) self.key = key
def decrypt(cls, ciphertext_and_tag, aad, key, iv): try: return aead.AESGCM(key).decrypt(iv, ciphertext_and_tag, aad) except cryptography.exceptions.InvalidTag: raise ProtectionInvalid("Tag invalid")
def encrypt(cls, plaintext, aad, key, iv): return aead.AESGCM(key).encrypt(iv, plaintext, aad)
def get_aead_cipher(key, method): # method should be AEAD method if method.startswith('aes'): return aead.AESGCM(key) return SodiumAeadCrypto(method, key)
def get_aead_cipher(key, method): '''get_aead_cipher method should be AEAD method''' if method.startswith('aes'): return aead.AESGCM(key) return aead.ChaCha20Poly1305(key)
def on_message(client, userdata, msg): global parameters global hmac_key global b_public_key_number global a_private_key global a_public_key global a_private_key_ecdh global a_public_key_ecdh global key_fernet global f_key global a_key if (msg.topic == (name + "/to")): # Receive params if (str(msg.payload.decode()).split(":")[0] == "param"): b_pem = str(msg.payload.decode()).split(":")[1] parameters = load_pem_parameters(bytes(b_pem, 'ascii'), backend=default_backend()) # Calculate keys from params a_private_key = parameters.generate_private_key() a_public_key = a_private_key.public_key() client.publish(name + "/from", "public:" + str(a_public_key.public_numbers().y)) # Receive public key elif (str(msg.payload.decode()).split(":")[0] == "public"): print("Public key received from platform.") # DH if (asymmetric_mode == 0): b_public_key_number = int( str(msg.payload.decode()).split(":")[1]) peer_public_numbers = dh.DHPublicNumbers( b_public_key_number, parameters.parameter_numbers()) b_public_key = peer_public_numbers.public_key( default_backend()) # Calculate shared key a_shared_key = a_private_key.exchange(b_public_key) # ECDH else: # Generate private and public key ECDH a_private_key_ecdh = ec.generate_private_key(ec.SECP384R1()) a_public_key_ecdh = a_private_key_ecdh.public_key() b_public_key_number = str(msg.payload.decode()).split(":")[1] b_public_key = load_pem_public_key( b_public_key_number.encode()) client.publish( name + "/from", "public:" + a_public_key_ecdh.public_bytes( encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo).decode()) # Calculate shared key a_shared_key = a_private_key_ecdh.exchange( ec.ECDH(), b_public_key) print("Shared key calculated.") # Calculate HMAC def hebra(): global hmac_key # If device has just 'input', write HMAC key here if (mode == 0): hmac_key = str( input( "Introduce la clave que aparece en la plataforma: " )) # If device has 'output' or nothing, write HMAC key on web page else: hmac_key = str(os.urandom(2).hex()) print("HMAC KEY: " + hmac_key) # Calcula HMAC (DH or ECDH) if (asymmetric_mode == 0): h = hmac.new( bytes(hmac_key, 'ascii'), bytes(str(a_public_key.public_numbers().y), 'ascii'), hashlib.sha256) else: h = hmac.new( bytes(hmac_key, 'ascii'), a_public_key_ecdh.public_bytes( encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo), hashlib.sha256) # Send to platform HMAC client.publish(name + "/from", "hmac:" + str(h.hexdigest())) if (hmac_key is None): # New thread because 'input' is blocking threading.Thread(target=hebra).start() # Calculate FERNET key using HASH derived_key_fernet = HKDF( algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data').derive(a_shared_key) key_fernet = base64.urlsafe_b64encode(derived_key_fernet) f_key = Fernet(key_fernet) # Calculate AEAD key using HASH derived_key_aead = HKDF( algorithm=hashes.SHA256(), length=24, salt=None, info=b'handshake data').derive(a_shared_key) key_aead = base64.urlsafe_b64encode(derived_key_aead) a_key = aead.AESGCM(key_aead)