要解析以 PEM 格式存储的密钥,您可以使用 openssl 模块:sudo gem install openssl
使用此模块,您将通过以下方式提取私钥:OpenSSL::PKey::EC.new(pemcontent).private_key
请注意,您的私钥基于 secp256k1 椭圆曲线:
% openssl ec -text 2>&1 << EOF | grep OID
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIBAFWFAlCWPb8IvM4yHLLKBIN/mEJU9cZnM5JD2U2EmAoAcGBSuBBAAK
oUQDQgAErMGUjbHcEf7Gk9gVOOlWdqSaGc0YhE5HBPqhoniBUG8MTx5AT7mxtuyn
QkydMeOciHyvvyU0gf81UW9udef2nA==
-----END EC PRIVATE KEY-----
EOF
ASN1 OID: secp256k1
因此,给EDSA.sign() 的第一个参数必须是ECDSA::Group::Secp256k1。这是一个包含定义这条曲线的参数的对象。
最后,这是您的代码,我已对其进行了必要的更改以使其正常工作:
require 'ecdsa'
require 'openssl'
def sign(str)
pemcontent = "-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIBAFWFAlCWPb8IvM4yHLLKBIN/mEJU9cZnM5JD2U2EmAoAcGBSuBBAAK
oUQDQgAErMGUjbHcEf7Gk9gVOOlWdqSaGc0YhE5HBPqhoniBUG8MTx5AT7mxtuyn
QkydMeOciHyvvyU0gf81UW9udef2nA==
-----END EC PRIVATE KEY-----"
digest = Digest::SHA256.digest(str)
temp_key = str.size
signature = ECDSA.sign(ECDSA::Group::Secp256k1, OpenSSL::PKey::EC.new(pemcontent).private_key, digest, temp_key)
return signature
end
注意:temp_key 的值应该以比使用消息长度签名更随机的方式生成,就像您在示例代码中所做的那样(它是 very very 坏主意,因为迟早你会签署两条长度相同的消息,这可能会让你的私钥被发现)。