简短的回答
假设所有内容都定义为它们在您的代码段中,具有分离的签名,没有到受信任根的证书链,证书
crt
,签名
signed
和数据
data
,以下应该做你想要的:
store = OpenSSL::Store.new
p7 = OpenSSL::PKCS7.new(signed.to_der)
verified = p7.verify([crt], store, data,
OpenSSL::DETACHED || OpenSSL:
:NOVERIFY)
</code>
(我没有测试过,YMMV)
全文
以下是我如何找到这个的完整故事,其中包含我所使用的所有资源的链接,因此如果您需要更多信息,您可以在某处查看。
我们发现,看看OpenSSL :: PKCS7文档
这一点点智慧
:
的
PKCS7.new =&gt; PKCS7
</强>
的
PKCS7.new(string)=&gt; PKCS7
</强>
本课程中的许多方法都没有记录。
一个快速的谷歌也没有改变任何东西。这表明我们将不得不采取更极端的措施。我们做一个
Google代码搜索
对于使用OpenSSL :: PKCS7验证签名的任何人。
嗯。我们发现
一些测试用例
。非常好;至少它有单元测试,可以帮助显示功能确实有效,并提供它的工作原理演示。
store = OpenSSL:
:Store.new
store.add_cert(@ca_cert)
ca_certs = [@ca_cert]
data = “aaaaa\r\nbbbbb\r\nccccc\r\n”
tmp = OpenSSL::PKCS7.sign(@ee1_cert, @rsa1024, data, ca_certs)
p7 = OpenSSL:
:PKCS7.new(tmp.to_der)
certs = p7.certificates
signers = p7.signers
assert(p7.verify([], store))
assert_equal(data, p7.data)
</code>
那不算太糟糕。包装证书商店。对您的数据进行签名,然后从签名数据中创建一个新的OpenSSL :: PKCS7对象。然后,你可以打电话
certificates
在它上面提取它签署的证书链,
signers
提取签名者,和
verify
可以调用以验证签名是否有效。您似乎将包含可信CA证书的证书存储作为要验证的第二个参数传递。您可以通过调用来提取数据
data
在上面。
但第一个论点意味着什么?在我们的测试用例中似乎没有人传递任何东西,只有第一个参数的空列表。嗯。一个谜。我们会回过头来看看。
第三个,可选的,参数
verify
看起来像它用于
验证分离的签名
:
data = “aaaaa\nbbbbb\nccccc\n”
flag = OpenSSL:
:BINARY|OpenSSL:
:DETACHED
tmp = OpenSSL::PKCS7.sign(@ee1_cert, @rsa1024, data, ca_certs, flag)
p7 = OpenSSL:
:PKCS7.new(tmp.to_der)
a1 = OpenSSL::ASN1.decode(p7)
certs = p7.certificates
signers = p7.signers
assert(!p7.verify([], store))
assert(p7.verify([], store, data))
</code>
回到第一个论点。当我们进行代码搜索时,我们发现的不仅仅是测试用例;我们还发现了一些其他用途。事实上,第二个似乎是
使用第一个参数
:
喔好吧。这是要检查的证书列表。现在有第四个参数,它似乎由标志组成。检查
OpenSSL文档
,我们看到这个不直观的名称(使用NOVERIFY标志验证?)意味着您应该只检查传入的证书和签名中嵌入的证书的签名,而不是尝试针对您的可信CA存储验证整个证书链。
这都是有用的信息,但我们有什么遗漏?值得庆幸的是,Ruby是开源软件,因此我们可以“使用源代码,Luke!”在谷歌代码搜索上乱七八糟之后,我们发现了
的定义
ossl_pkcs7_verify
。一旦你超越了有些神秘的名字,代码就可以直接阅读;它基本上只是将其参数转换为OpenSSL可以理解的格式,并调用:
ok = PKCS7_verify(p7, x509s, x509st, in, out, flg);
</code>
所以,它看起来像
那’
我们真正想要寻找文件的地方。
描述
PKCS7_verify()
验证PKCS#7 signedData结构。
的
P7
</强>
是要验证的PKCS7结构。
的
证书
</强>
是一组用于搜索签名者证书的证书。
的
商店
</强>
是一个值得信赖的证书商店(用于链验证)。
的
INDATA
</强>
是内容不存在的签名数据
的
P7
</强>
(这是分离的)。内容写入
的
出
</强>
如果它不是NULL。
</p>
<P>
的<strong>
旗
</强>
是一组可选的标志,可用于修改验证
操作。
</p>
<P>
<code>
PKCS7_get0_signers()
</code>
从中检索签名者的证书
的<strong>
P7
</强>
它确实如此
的<strong>
不
</强>
检查其有效性或签名是否有效。该
的<strong>
证书
</强>
和
的
旗
</强>
参数与中的含义相同
PKCS7_verify().
见
完整的男人页
更多细节。
哦,作为旁注,我找到了
这个警告
在搜索时;它看起来像在Ruby 1.9中,并且可能在一些更高版本的Ruby 1.8中,该类已从冗余的OpenSSL :: PKCS7 :: PKCS7转移到OpenSSL :: PKCS7。
warn(“Warning: OpenSSL:
:PKCS7 is deprecated after Ruby 1.9; use OpenSSL::PKCS7 instead”)
</code>