ECC 公钥长度不同于位表示

信息安全 公钥基础设施 openssl 密钥生成 电子抄送
2021-08-30 11:05:06

使用手册中的以下命令使用 OpenSSL 生成的 256 位 ECC 密钥对(256 位应该是公钥的长度):

openssl ecparam -name secp256k1 -genkey -noout -out key.pem

和相应的公钥:

openssl ec -in key.pem -out public.pem -pubout

public.pem 文件包含一个 base64 编码的字符串,例如:

-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEdPzYnkmkF8oy+R+FcByIbyPBE2l6HHOJ
mfZWtAaFZyIx9WPSzZTdyjmWlFqLvwaFlHu9OX9e7Snslfw7nneDIw==
-----END PUBLIC KEY-----

公钥由一个点(x 和 y 坐标)和使用的曲线组成。

解码后,每个坐标都是一个 256 位长的数字,而密钥本身绝不是 256 位长。这个对吗?

我的目标是尽可能缩短公钥长度,同时在我的应用程序中保持安全性,我不明白为什么建议的“256 位公钥”实际上是两倍多。

1个回答

对于某个整数q ,椭圆曲线是在大小为q的有限域上定义的每个曲线元素是一个,有两个坐标XY,它们是曲线元素。

曲线的“大小”是其密码强度的重要参数,接近q可以看出,总曲线大小n是这样的|n - (q + 1)| ≤ 2*sqrt(q)(这是哈斯定理)。因此,如果您想要一个“256 位曲线”,您将需要一个 256 位字段。

但是,公钥是一个曲线点,由两个坐标表示。所以你最终会得到两个256 位的值,即公钥大小。此外,标准公钥格式还包括一些参数,这些参数指定公钥是“椭圆曲线”类型,并引用该点所在的实际曲线。我们仍然称其为“256 位公钥”,因为该数字与密钥的加密强度有关,而不是与实际编码大小有关。


如果我们再深入一点,我们可能会注意到,根据定义,所有曲线点都必须满足曲线方程,通常Y 2 = X 3 + aX + b对于两个常数ab(这些常数实际上定义了曲线)。因此,如果您知道X,那么您可以使用曲线方程计算Y 2 。由于我们在一个领域工作,一个元素在该领域中最多有两个平方根,所以从Y 2你可以得到Y-Y这允许点压缩:将点(X,Y)表示为仅X, 加上一位Y(这足以区分Y-Y)。使用点压缩,一个 256 位的 EC 公钥适合 257 位(假设有关使用的曲线的信息是通过其他方式传输的)。

不幸的是,点压缩虽然很漂亮,但似乎在某些时候已经获得了专利,所以很多现有的实现不支持它,即使它是“标准的”(它在 ANS X9.62-2005 中有描述)。从“RFC”的角度来看,点压缩的支持是可选的。因此,使用它会导致失去互操作性的风险。

(不知道OpenSSL是否支持点压缩,应该测试一下。)