# WhatsappFlowCrypto
If you want to implement a [WhatsApp Flow-Endpoint](https://developers.facebook.com/docs/whatsapp/flows/guides/implementingyourflowendpoint)
you need to implement the specified workflow to [decrypt the request and encrypt the response.](https://developers.facebook.com/docs/whatsapp/flows/guides/implementingyourflowendpoint#request-decryption-and-encryption)
For many tasks you can use the Erlang [`crypto`](https://www.erlang.org/doc/apps/crypto/crypto.html) module, but unfortunately this is not possible at the time of writing
in this case because the necessary configuration of the block cipher is not supported:
To decrypt the AES key you need
> RSA/ECB/OAEPWithSHA-256AndMGF1Padding algorithm with SHA256 as a hash function for MGF1;
Once the AES key is decrypted we can do the rest of the workflow using the `crypto` module.
This package contains a Rust implementation to decrypt the encrypted AES key. With the help
of [Rustler](https://github.com/rusterlium/rustler) a safe NIF binding is created
and the missing function can be compensated quickly and efficiently.
## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `whatsapp_flow_crypto` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:whatsapp_flow_crypto, "~> 0.1.0"}
]
end
```
## Private key
The package provides a function to extract the private key (with or without a password) from a pem string.
To create the private/public key you can use then `openssl` tool. In the following example
we will create an encrypted private key using the AES-128 cipher (**DES3 cipher is not supported anymore**).
The last command exports the private key without encryption.
```bash
openssl genrsa -aes128 -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private.pem -out unencrypted-private.pem
```
## Basic usage
Loading the private key:
```elixir
{:ok, private_key_pem} = File.read(private_pem_path);
WhatsappFlowCrypto.fetch_private_key(private_key_pem, "test")
{:ok, #Reference<0.1652491651.443678740.227250>}
```
Decrypt the request and encrypt the response:
```elixir
WhatsappFlowCrypto.decrypt_request(private_key_ref, encrypted_aes_key, initial_vector, encrypted_flow_data)
{:ok, {decrypted_body, aes_key, initial_vector}}
WhatsappFlowCrypto.encrypt_response(aes_key, initial_vector, %{"Hello" => "World"})
"KUkRnUDAUKqhiovnQ9RRwmdBjcg87/wh+ZrMtbh8xlx3"
```
For the detail see the `WhatsappFlowCrypto`.
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/whatsapp_flow_crypto>.