Verifying web crypto signatures in erlang/Elixir

The JS API returns a ‘raw’ signature, whereas OTP’s :public_key API expects a DER-encoded signature.

Try this:

message = "abc"

encoded_signature = "AOqjfvb1P0fYdbnq+f3XsbOR/Lylq4csC5e1Ks4cKRTcWKQyH4CVr/XRHCmZDEWOpaA8gwuM3Z3qD21vMaixySUPASTDnd1J8shNx51MCbONIReTNuH53kzxykLpf0riSyMbEBQtie4/pxlrolUOsDja2f/ikgM/lGXtCTXz2faV4m2Y"

public_PEM = "-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB7PNQVbADLNyobtijE5NVZUvHs74h
iMntCbp0C8pdU1IQRWlAfDeEs/iuxA32VARw9Q5/0mim8Si8JcpCJnhS0u8AESMf
Ux3WqzHhB33t4q3iPsJbM7zmN91QNnbYErrGqEDCmSruPpKw1iK5dJ3/xQZbkpmR
ztoVwrZoCoGUu+WTqEI=
-----END PUBLIC KEY-----"

raw_signature = Base.decode64!(encoded_signature)
size = div(byte_size(raw_signature), 2)
<<r::binary-size(size), s::binary-size(size)>> = raw_signature
signature = <<48, 129, 136, 2, size, r::binary, 2, size, s::binary>>

[key_entry] = :public_key.pem_decode(public_PEM)
public_key = :public_key.pem_entry_decode(key_entry)

:public_key.verify(
  message,
  :sha256,
  signature,
  public_key
)
# returns true
7 Likes