我想用 签名哈希openssl pkeyutl
并用 验证openssl dgst -verify
。
下面是我测试的私钥和公钥(EC 密钥):
私人.pem:
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFYL7prqjwKcVpKp4VF0kSshVoNCu3QzFeJHjvq78n4FoAoGCCqGSM49
AwEHoUQDQgAEkcL/M+0hEuW/VUNCZT5Jc1pyw9gm4vphWldTdAqMJhC8eTiP/gao
rTkz6+iFfOPbJTEzRD8y36WqYAlS+65W8A==
-----END EC PRIVATE KEY-----
公共.pem:
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkcL/M+0hEuW/VUNCZT5Jc1pyw9gm
4vphWldTdAqMJhC8eTiP/gaorTkz6+iFfOPbJTEzRD8y36WqYAlS+65W8A==
-----END PUBLIC KEY-----
$ echo -n "123456" | openssl dgst -sha256
8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
S̶H̶A̶-̶2̶4̶5̶ 123456 的 SHA-246 是8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
.
让我们用 pkeyutl 签署 SHA256(123456)
$ echo -n "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92" | openssl pkeyutl -inkey private.pem -sign | openssl base64 -e -A
MEYCIQDIJHf2SQJliMNvPwgCqanzqWxleK/YGSCd15RK8IYPEQIhAOlcvXH9ASQRMRNgKgMr4ZZLL3nyaCsTHBeU0iReZMmp
所以我们有base64编码的签名MEYCIQDIJHf2SQJliMNvPwgCqanzqWxleK/YGSCd15RK8IYPEQIhAOlcvXH9ASQRMRNgKgMr4ZZLL3nyaCsTHBeU0iReZMmp
现在让我们验证openssl pkeyutl -verify
$ openssl pkeyutl -verify -pubin -inkey public.pem -sigfile <(echo -n "MEYCIQDIJHf2SQJliMNvPwgCqanzqWxleK/YGSCd15RK8IYPEQIhAOlcvXH9ASQRMRNgKgMr4ZZLL3nyaCsTHBeU0iReZMmp" | openssl enc -A -base64 -d ) -in <(echo -n "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92")
Signature Verified Successfully
所以已经验证成功。
现在是有问题的部分:所以我们要签名的原始数据是“123456”。让我们用openssl dgst
这个:
$ echo -n "123456" | openssl dgst -sha256 -verify public.pem -signature <(echo -n "MEYCIQDIJHf2SQJliMNvPwgCqanzqWxleK/YGSCd15RK8IYPEQIhAOlcvXH9ASQRMRNgKgMr4ZZLL3nyaCsTHBeU0iReZMmp" | openssl enc -A -base64 -d)
Verification Failure
返回验证失败。
从原始“123456”文本创建 sha256 摘要时是否openssl dgst
做其他事情?
据我了解,它应该可以工作,因为pkeyutl
签名的sha256
哈希值与通过openssl dgst -sha256
. 在这里,我们使用相同的私钥和公钥,所以我不明白为什么openssl dgst -verify
无法验证通过生成的签名pkeyutl
,
TLDR:这是十六进制
并不真地。我们经常把这种事情说成是一种捷径或约定,但你似乎误解了它。是以十六进制显示
8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
的 SHA-256,意思是 base-16,我们通常缩写为十六进制,或者我们也称其为“编码为”或“表示为”十六进制。实际的哈希值是 32 字节的任意位,这些位不构成字符,因此无法正确显示、发布到 Stack 或以其他方式被人类使用;这就是为什么我们几乎总是使用 hex 或 base64 来处理程序和文件之外的此类数据。(更准确地说,哈希是256 位,在使用 8 位字节的系统或设备上只有 32字节123456
-- 不是所有的都可以,但是你作为普通用户遇到的所有的都是这样。特别是,OpenSSL 工作的所有设备都使用 8 位字节,因此OpenSSL SHA-256 是 32 字节。)您需要将十六进制表示形式转换回实际数据——在 Unix 上有几个选项在这里被众多 Q 或 serverfault 或 unix.SX 覆盖,但在 Windows 上较少(在 WSL 之外,实际上是 Unix)——或使用
dgst -binary
which 不首先创建十六进制表示,因此更简单:PS:注意不是所有版本都
echo
支持-n
;见https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo