I'm trying to check if a signature is valid, in Node.js I would use
https://nodejs.org/api/crypto.html#crypto_verify_verify_object_signature_signatureencoding
I can't seem to find anything for crystal that provides this functionality?
This is currently not implemented in the standard library, but we can find a shard that does it: openssl_ext. This shards closely resembles the Ruby API, so let's get going!
First we need a key:
$ openssl genpkey -algorithm rsa -out key.pem
$ openssl rsa -in key.pem -pubout -out pub.pem
Then we need to create a shard and add the dependency:
$ shards init
$ $EDITOR shards.yml
dependencies:
openssl_ext:
github: randomstate/openssl_ext
$ shards
A small program to sign something:
$ $EDITOR sign.cr
require "openssl_ext"
require "base64"
private_key = OpenSSL::RSA.new File.read(ARGV[0])
digest = OpenSSL::Digest.new("SHA1")
data = ARGV[1]
signature = private_key.sign digest, data
puts Base64.encode signature
$ crystal build sign.cr
And a small program to verify a signature:
$ $EDITOR verify.cr
require "openssl_ext"
require "base64"
public_key = OpenSSL::RSA.new File.read(ARGV[0]), is_private: false
digest = OpenSSL::Digest.new("SHA1")
data = ARGV[1]
signature = Base64.decode STDIN.gets_to_end
puts public_key.verify(digest, signature, data) ? "Valid" : "Invalid"
$ crystal build verify.cr
Let's test our work:
$ ./sign key.pem Hello | ./verify pub.pem Hello
Valid
$ ./sign key.pem Hello | ./verify pub.pem Bye
Invalid