在 erlang 中将数据块签名为散列不起作用。基于ec的密钥推导

signing of datablock as hash in erlang not working. Key derivation based on ec

二郎版本:9.2

我正在尝试使用 ecdh-base 上生成的密钥对一个数据块进行签名。

这是我的工作流程:

86> {PublicKey, PrivKeyOut} = crypto:generate_key(ecdh, crypto:ec_curve(secp521r1)).
{<<4,0,196,6,85,178,189,234,231,13,82,152,96,162,92,163,
   133,81,42,147,168,146,138,226,15,80,127,228,...>>,
 <<1,33,215,135,89,40,35,40,104,14,217,153,78,62,53,83,
   198,165,84,30,135,159,218,82,47,102,204,...>>}
87> Mesage = "testmessage".
"testmessage"
88> Hash = crypto:hash(sha512, Mesage).
<<1,216,98,78,245,111,176,233,114,224,249,27,118,114,49,
  189,40,144,90,249,175,108,79,235,186,247,247,40,131,...>>
89> Signature = crypto:sign(ecdsa, sha512, Hash, PrivKeyOut).
** exception error: bad argument
     in function  crypto:pkey_sign_nif/5
        called as crypto:pkey_sign_nif(ecdsa,sha512,
                                       <<1,216,98,78,245,111,176,233,114,224,
                                         249,27,118,114,49,189,40,144,90,249,
                                         175,108,79,235,186,247,...>>,
                                       <<1,33,215,135,89,40,35,40,104,14,217,
                                         153,78,62,53,83,198,165,84,30,135,159,
                                         218,82,47,...>>,
                                       [])
     in call from crypto:sign/5 (crypto.erl, line 433)

我做错了什么?

我发现了旧的 erlang 错误,这些错误表明椭圆曲线密码套件没有完全实现。 这里的网址:

http://erlang.2086793.n4.nabble.com/Incomplete-Elliptic-Curve-Cipher-Suites-in-R16B01-and-R16B02-td4692857.html http://erlang-bugs.erlang.narkive.com/YNWGZ1F2/incomplete-elliptic-curve-cipher-suites-in-r16b01-and-r16b02

我会使用 libsodium 库进行测试:

https://github.com/jlouis/enacl

感谢

您的代码有两个问题:

  • crypto:sign/4 的第 4 个参数称为 Key,但如果您检查 type spec,它实际上需要一个 [ecdh_private(), ecdh_params()] 列表(如果使用ecdsa 算法至少)。
  • 如果自己计算Hash,则第三个参数为{digest, Hash}。否则,您将签署消息散列的散列。您也可以将纯消息传递给函数,但在这种情况下,它必须是二进制,而不是字符串。

这是解决这些问题的方法:

EcdhParams = crypto:ec_curve(secp521r1),
{PublicKey, PrivKeyOut} = crypto:generate_key(ecdh, EcdhParams),
Message = <<"testmessage">>,
crypto:sign(ecdsa, sha512, Message, [PrivKeyOut, EcdhParams]).

或者,如果您稍后需要 Hash and/or,您会得到 Message 作为字符串,这也可以工作:

EcdhParams = crypto:ec_curve(secp521r1),
{PublicKey, PrivKeyOut} = crypto:generate_key(ecdh, EcdhParams),
Message = "testmessage",
Hash = crypto:hash(sha512, Message),
crypto:sign(ecdsa, sha512, {digest, Hash}, [PrivKeyOut, EcdhParams]).