提问者:小点点

ECIES:KDF的正确ECDH输入方式?安全效果?


为了完全理解ECIES并使用我最喜欢的库,我自己实现了ECIES的一些部分。这样做并比较结果导致了一个我不太清楚的点:KDF的输入到底是什么?

ECDH的结果是一个向量,但是你对KDF使用什么呢?它只是X值,还是X Y(可能带有前置的04)?你可以在野外找到这两个概念,为了可重复性,哪种方式是正确的方式会非常有趣(如果有正确的方式——我知道ECIE更像是一个概念,有几个自由度)。

解释(如果我在特定的点上错了,请纠正我)。如果我谈论字节长度,这将指具有256位EC键的ECIES。

所以,首先,大局:这是ECIES过程,我说的是第2步-

接收者的公钥是向量V,发送者的强调私钥是标量u,密钥协商函数KA是ECDH,基本上是V*u的乘法。结果,你得到一个共享密钥,它也是一个向量——让我们称之为“共享密钥”。

然后,您获取发送者的公钥,将其与共享密钥连接,并将其用作密钥导出函数KDF的输入。

但是:如果您想将此向量用于键派生函数KDF,您有两种方法:

  1. 您可以只使用共享键的X。然后您有一个32字节的字节串。
  2. 您可以使用共享密钥的X和Y并将其作为公钥添加到0x04。然后您有一个01 32 32字节的字节串[3)只是为了完整:您也可以使用X Y作为压缩点)

字节串的长度并不重要,因为在KDF(通常涉及散列)之后,您总是有一个固定值,例如32字节(如果您使用sha256)。

但是当然,如果你选择一种或另一种方法,KDF的结果是完全不同的。所以问题是:正确的方法是什么?

  • eciespy使用方法2https://github.com/ecies/py/blob/master/ecies/utils.py#L143
  • python密码学在ECDH:https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/#cryptography.hazmat.primitives.asymmetric.ec.ECDH中只返回了X。他们没有ECIES支持。
  • 如果我理解CryptoC的留档正确,他们也只是给X回:https://cryptopp.com/wiki/Elliptic_Curve_Diffie-Hellman
  • 与JavaBountyCastle相同,如果我没看错-结果是一个整数:https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java#L79
  • 但是你也可以找到同时包含X和Y的在线计算器:http://www-cs-students.stanford.edu/~tjw/jsbn/ecdh.html

所以,我试图在留档中获取更多信息:

  • 有ECIES的ISO。他们没有详细描述它(或者我找不到它),但我会将其解释为完整向量X和Y的方式:https://www.shoup.net/papers/iso-2_1.pdf
  • 有一篇在网上被广泛链接的论文,指的是在第27页只用X:http://www.secg.org/sec1-v2.pdf

所以,结果是:我很困惑。有人能给我指出正确的方向吗,或者这只是你拥有的一定程度的自由(以及在兼容性方面有很多乐趣的理由)?


共1个答案

匿名用户

回答我自己的问题:是的,这是一个自由度。X坐标方式被称为紧凑表示,它在RFC6090中定义。所以两者都是有效的。

它们也同样安全,因为可以如附录CRFC6090中所述从X中计算出Y。

默认方式是使用紧凑表示。这两种方式彼此不兼容,所以如果您偶然发现库之间的兼容性问题,这可能是一个有趣的发现点。