为了完全理解 ECIES 并使用我最喜欢的库,我自己实现了 ECIES 的某些部分。这样做并比较结果会导致我不太清楚的一点:KDF 的输入到底是什么?
ECDH的结果是一个向量,但是你用什么来做KDF呢?它只是 X 值,还是 X + Y(可能带有前置 04)?您可以在野外找到这两个概念,并且为了互操作性,哪种方式是正确的方式真的很有趣(如果有正确的方式 - 我知道 ECIE 更像是一个概念并且有几个自由度)。
解释(如果我在特定点上错了,请纠正我)。如果我谈论字节长度,这将指的是具有 256 位 EC 密钥的 ECIES。
所以,首先,大局:这是 ECIES 流程,我说的是第 2 步 -> 第 3 步:
接收者的公钥是向量 V,发送者的临时私钥是标量 u,密钥协商函数 KA 是 ECDH,它基本上是 V * u 的乘积。结果,您得到了一个共享密钥,它也是一个向量——我们称之为“共享密钥”。
然后获取发送者的公钥,将其与共享密钥连接,并将其用作密钥派生函数 KDF 的输入。
但是:如果您想将此向量用于密钥派生函数 KDF,您有两种方法:
- 你可以只使用共享密钥的 X。然后你有一个 32 字节的字节串。
- 您可以使用共享密钥的 X 和 Y,并像使用公钥一样在其前面加上 0x04。然后你有一个 01 + 32 + 32 字节的字节串 [3) 只是为了完整:你也可以使用 X + Y 作为压缩点)
字节串的长度并不重要,因为在 KDF(通常涉及散列)之后,您总是有一个固定值,例如 32 个字节(如果您使用 sha256)。
但是,如果您选择其中一种方法,KDF 的结果当然会大不相同。所以问题是:正确的方法是什么?
- eciespy 使用方法 2 https://github.com/ecies/py/blob/master/ecies/utils.py#L143
- python cryptography 在他们的 ECDH 中只返回 X:https ://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/#cryptography.hazmat.primitives.asymmetric.ec.ECDH 。他们没有 ECIES 支持。
- 如果我正确理解 CryptoC++s 文档,他们也只会返回 X:https ://cryptopp.com/wiki/Elliptic_Curve_Diffie-Hellman
- 与 Java BountyCastle 相同,如果我没看错的话 - 结果是一个整数: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
所以,结果是:我很困惑。谁能指出我正确的方向,或者这只是你拥有的一定程度的自由(以及在兼容性方面有很多乐趣的理由)?