Not sure how to generate an ECDSA signature, given a private key and a message

落花浮王杯 提交于 2019-12-05 09:02:49

It appears that the documentation and the actual API for Ruby’s OpenSSL EC support are both currently rather lacking. In particular, in Ruby <= 2.3.1 the OpenSSL::PKey::EC doesn’t follow the same API as RSA and DSA keys for signing and verifying. What you would want to do, but currently can’t with EC keys, is this (all the code here assumes you have called require 'openssl' somewhere):

# Get the key, here I'm reading the file
priv_key = OpenSSL::PKey.read(File.read('eckey.pem')) 

# This should be the appropriately formatted string
data = "some data to sign"

# The hash algorithm, I assume SHA256 is being used
digest = OpenSSL::Digest::SHA256.new

# This doesn't work in 2.3.1, but does in 2.4.0-preview1
signature = priv_key.sign(digest, data)

As I note in the comments, this does work in Ruby 2.4.0-preview1, but that’s likely not much use to you.

To get it working with current Ruby, you need to do something like this:

# As before:
priv_key = OpenSSL::PKey.read(File.read('eckey.pem'))
data = "some data to sign"

signature = priv_key.dsa_sign_asn1(OpenSSL::Digest::SHA256.digest(data))

Both these techniques give you a binary string. I think you will need to base64 encode it before adding it as your request header.

To extract the public key to check the signature verifies is also a bit tricky (although you could just use the openssl command line and read in the file). The public_key methods returns an OpenSSL::PKey::EC::Point object rather than an actual key, so we need to recreate one from the private key. The verify method does work on Ruby 2.3.1:

pub = OpenSSL::PKey::EC.new(priv_key.group)
pub.public_key = priv_key.public_key

data = "some data to sign"
digest = OpenSSL::Digest::SHA256.new

puts pub.verify(digest, sig, data)

The Apple page doesn’t appear to specify the hash algorithm to use, but from what I’ve seen it looks like SHA-256 is right. (Also I could have got this completely wrong and Apple are using a completely different format. I’d be keen to know whether or not this code works you you).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!