在给定私钥和消息的情况下,不确定如何生成ECDSA签名

我正在按照Apple的指南撰写CloudKit Web服务请求。 我遇到问题的是第2步,在“validationWeb服务请求”下:

  1. 使用您的私钥计算此消息的ECDSA签名。

在达到这一点之前,我生成了我的证书,一个.pem文件,当在文本编辑器中打开它时显示我的私钥,所以我也有字符串格式。

我还遵循了生成它所指的消息的步骤,我现在将其作为字符串。

因此,假设我有一个私钥(或者.pem文件,如果需要的话),以及一个消息作为字符串,理论上我应该很容易获得使用我的私钥计算的消息的ECDSA签名。 但这就是我在努力的地方。 我在网上找到的图书馆似乎采用了一种更为复杂的方法,包括不同的移动部件,没有引用.pem文件以及关于生成新的公钥/私钥的讨论。

任何有关此步骤的帮助将不胜感激。

看来Ruby和OpenSSL EC支持的文档和实际API目前都缺乏。 特别是,在Ruby <= 2.3.1中, OpenSSL::PKey::EC不遵循与RSA和DSA密钥相同的API进行签名和validation。 您想要做什么,但目前不能使用EC密钥,这是(这里的所有代码都假定您在某处调用了require 'openssl' ):

 # 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) 

正如我在评论中所指出的,这在Ruby 2.4.0-preview1中确实有效,但这对您来说可能没用多少。

要使它与当前的Ruby一起使用,您需要执行以下操作:

 # 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)) 

这两种技术都为您提供了二进制字符串。 我认为在将其添加为请求标头之前,您需要对其进行base64编码。

提取公钥以检查签名validation也有点棘手(尽管您可以使用openssl命令行并读入文件)。 public_key方法返回OpenSSL::PKey::EC::Point对象而不是实际键,因此我们需要从私钥中重新创建一个。 verify方法适用于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) 

Apple页面似乎没有指定要使用的哈希算法,但从我看到它看起来像SHA-256是正确的。 (我也可能完全错了,Apple正在使用完全不同的格式。我很想知道这段代码是否适合你)。