2017 年 12 月 28 日更新 – 3:
OpenSSL DSTU 模块的作者提供补丁对 OpenSSL+DSTU 实现进行了修复并提供了进一步的帮助。
我首先可以使用以下命令完成我需要做的事情:
./apps/openssl smime -verify -noverify -in my_message.txt.p7s -engine dstu -inform DER
engine "dstu" set.
Hello, world!
Verification successful
后来连接证书链中bundle.pem
,我可以这样做:
./apps/openssl smime -verify -CAfile bundle.pem -in /yo/my_message.txt.p7s -engine dstu -inform DER
engine "dstu" set.
Hello, world!
Verification successful
2017 年 12 月 28 日更新 – 2:
OpenSSL DSTU 模块的作者确认,该模块目前无法正常工作——https://github.com/dstucrypt/openssl-dstu/issues/2#issuecomment-354288000。
我想我得去别处寻找合适的 DSTU4145 实现。我刚刚了解到一个 BountyCastle 项目,它规格包括 DSTU-4145。我猜除了编写一些 Java 代码来执行签名验证之外,没有别的选择。
2017 年 12 月 28 日更新 – 1:
这是我的文件:
- 需要验证的消息:https://www.dropbox.com/s/pt7ms096lygz8es/my_message.txt.p7s?dl=0
- 需要验证的消息,采用 ASN.1 格式:https://gist.github.com/gmile/a9bb5cb57fc8195d74029251eb3946ba
- 我正在尝试验证的证书:https://acsk.privatbank.ua/arch/docs/PrivatBank.zip
我有一个文件,由某人用他的私钥签名:signed_content.txt
。我还有一个来自 CA 的证书。私钥和证书以某种方式相互关联。
如何验证文件上的签名?
这就是我正在做的事情:
从证书中提取公钥(从授权机构获得):
openssl x509 -pubkey -inform der -in PrivateCerts/CA-3004751DEF2C78AE010000000100000049000000.cer -noout -engine dstu > public_key.txt
尝试验证文件的内容:
openssl rsautl -verify -in my_message.txt.p7s -inkey public_key.txt -pubin -engine dstu engine "dstu" set. openssl (lock_dbg_cb): already locked (mode=9, type=18) at md_rand.c:387 openssl (lock_dbg_cb): not locked (mode=10, type=18) at dstu_rbg.c:87 Error getting RSA key 139964169291424:error:0607907F:digital envelope routines:EVP_PKEY_get1_RSA:expecting an rsa key:p_lib.c:288:
还,我如何提取签名文件的实际内容?
我拥有的文件是否不正确?我可以查看它的 ASN.1 内容:
openssl asn1parse -inform DER -in my_message.txt.p7s -i
asn.1 结构看起来还不错(老实说,我对 ASN.1 了解得太少了):我可以看到一些关于组织和其他内容的字段。
我正在使用DSTU 发动机(乌克兰加密标准),类似于 GOST(俄罗斯加密标准)。
答案1
openssl rsautl
仅处理 RSA 算法,不处理任何其他算法:不是 DSA,不是 ECDSA,不是 GOST,不是 DSTU 等。openssl pkeyutl -sign/-verify
可以处理通过标准EVP
接口可用的任何算法,您的引擎大概应该如此。
然而,大多数签名算法实际上会签署一份哈希数据而不是原始数据。特别是我看到 BouncyCastle 有几种使用 GOST3411(哈希)和 DSTU4145(带或不带 LE 又名 Little-Endian 编码)的签名方案。为此,您要么需要显式哈希然后使用openssl pkeyutl
,要么更轻松地使用openssl dgst -$hashname -sign/-verify
为您组合它们。对于内置哈希,您可以将其缩写为,openssl $hashname -sign/-verify
但我不知道这是否适用于引擎哈希。
无论如何,您几乎肯定不想将所有signed_content.txt
内容视为数据,更不用说将其视为数据的哈希值了。如果它具有 ASN.1 结构,它可能包括签名数据(仅作为结构的一部分)加上签名值,以及可能的元数据甚至其他数据。如果它是一种常见的结构,并且您发布了结果asn1parse
,其中任何您认为敏感的数据值都被抑制,但所有元数据(如 OID)都完好无损,我或这里的其他人可能会识别它并提出建议。如果它是最多通用结构,CMS/PKCS7,OpenSSL 命令行可以直接处理。
答案2
如何验证文件上的签名?
openssl smime -verify ...
即使使用 dstu 引擎,简单的操作也应该可以工作:
$ openssl1.0 smime -verify -noverify -engine dstu -inform DER -in my_message.txt.p7s
engine "dstu" set.
Hello, world!
Verification successful
这是你需要的吗?当我删除该选项时-noverify
,我收到验证失败Verify error:unable to get local issuer certificate
,但它与证书自我验证有关,而不是消息。我的 openssl1.0 工具就像常规 openssl 1.0.2o,应用了 gost 和 dstu 补丁。