Please can you provide or point to replacement code for:
crypto — crypto v5.5 (erlang.org)
from here: Deprecations — Erlang/OTP v27.0.1
It seems several functions have no equivalents.
Functions Deprecated in OTP 27
code:lib_dir/2 (this functionality will be removed in a future release)
crypto:private_decrypt/4 (do not use)
crypto:private_encrypt/4 (use public_key:sign/3 instead)
crypto:public_decrypt/4 (use public_key:verify/4 instead)
crypto:public_encrypt/4 (do not use)
mnesia_registry:create_table/_ (use mnesia:create_table/2 instead)
public_key:decrypt_private/2 (do not use)
public_key:decrypt_private/3 (do not use)
public_key:decrypt_public/2 (use public_key:verify/4 instead)
public_key:decrypt_public/3 (use public_key:verify/5 instead)
public_key:encrypt_private/2 (use public_key:sign/3 instead)
public_key:encrypt_private/3 (use public_key:sign 4 instead)
public_key:encrypt_public/2 (do not use)
public_key:encrypt_public/3 (do not use)
ssl:prf/5 (Use export_key_materials/4 instead. Note that in OTP 28 the 'testing' way of calling this function will no longer be supported.)
I have been trying to redo : raw.githubusercontent.com/WhatsApp/WhatsApp-Flows-Tools/refs/heads/main/examples/endpoint/nodejs/basic/src/encryption.js
For a project but the samples are all coming back with depreciated functions. (Even ChatGPT and Copilot return incorrect code)
here is my effort so far:
defmodule Flows do
defmodule FlowEndpointException do
defexception [:message, :status_code]
@impl true
def exception({status_code, message}) do
%__MODULE__{message: message, status_code: status_code}
end
end
def decrypt_request(body, private_pem, passphrase) do
%{
"encrypted_aes_key" => encrypted_aes_key,
"encrypted_flow_data" => encrypted_flow_data,
"initial_vector" => initial_vector
} = body
private_key = :public_key.pem_entry_decode({:RSAPrivateKey, private_pem, passphrase})
try do
decrypted_aes_key =
encrypted_aes_key
|> Base.decode64!()
|> :crypto.decrypt(:rsa, private_key, [
{:rsa_padding, :rsa_pkcs1_oaep_padding},
{:rsa_oaep_md, :sha256}
])
flow_data_buffer = Base.decode64!(encrypted_flow_data)
initial_vector_buffer = Base.decode64!(initial_vector)
tag_length = 16
{encrypted_flow_data_body, encrypted_flow_data_tag} =
:erlang.split_binary(flow_data_buffer, byte_size(flow_data_buffer) - tag_length)
decrypted_json_string =
:crypto.crypto_one_time_aead(
:aes_128_gcm,
decrypted_aes_key,
initial_vector_buffer,
encrypted_flow_data_body,
"",
encrypted_flow_data_tag,
false
)
{
:ok,
%{
decrypted_body: Jason.decode!(decrypted_json_string),
aes_key_buffer: decrypted_aes_key,
initial_vector_buffer: initial_vector_buffer
}
}
rescue
_ ->
raise FlowEndpointException,
{421, "Failed to decrypt the request. Please verify your private key."}
end
end
def encrypt_response(response, aes_key_buffer, initial_vector_buffer) do
flipped_iv = for <<byte <- initial_vector_buffer>>, do: Bitwise.bnot(byte)
{cipher_text, cipher_tag} =
:crypto.crypto_one_time_aead(
:aes_128_gcm,
aes_key_buffer,
flipped_iv,
Jason.encode!(response),
"",
16,
true
)
Base.encode64(cipher_text <> cipher_tag)
end
end