RSA Crypto for JS and Elixir
Modern browsers have real crypto built in the class SubtleCrypto, to quote the MDN page:
The
SubtleCrypto
interface of the Web Crypto API provides a number of low-level cryptographic functions. Access to the features ofSubtleCrypto
is obtained through thesubtle
property of theCrypto
object you get fromWindow.crypto
.
An example of how to do public key encryption in Javascript using SubtleCrypto:
A Practical Guide to the Web Cryptography API
Mozilla Documentation for SubtleCrypto and examples on mdn github. There are links in the reference documentation to running examples on the mdn github.
The trick in using this is handling encrypted payloads outside of JS with the same parameters. The use case I'm interested in is encryption using a public key in JS and decryption with the private key in Elixir. On the JS side, the parameters are:
return await window.crypto.subtle.importKey( "spki", binaryDer, { name: "RSA-OAEP", hash: "SHA-256" }, true, ["encrypt"] );
The trouble is that RSA-OAEP with SHA-256 support on the openssl side is not available in recent older versions of openssl and while I've been able to use the openssl
command to do this successfully at one point with some version, I gave up on this approach to testing the process due to poor documentation.
However, doing this in Elixir with a recent openssl library and the erlang public_key module is not too difficult and looks like this:
Base.decode64!(input, padding: false )
|> :public_key.decrypt_private(
key,
rsa_padding: :rsa_pkcs1_oaep_padding,
rsa_oaep_md: :sha256 )