我想知道是否有(并且我希望有)ECDH(椭圆曲线Diffie-Hellman)和ECDSA(椭圆曲线数字签名算法)的公钥大小标准,适用于主要领域的每种曲线类型(192, 224,256,384和521)。
答案 0 :(得分:25)
如果您使用其中一条“命名曲线”,则公钥大小是固定的,并且取决于基础曲线的“字段大小”。
公钥大小还取决于是使用“未压缩”表示还是“压缩”表示。在未压缩的形式中,公钥大小等于字段大小的两倍(以字节为单位)+ 1,在压缩形式中,它是字段大小+ 1.因此,如果您的曲线在secp256r1
(also called NIST P-256
or X9.62 prime256v1
)上定义,则字段大小为256位或32字节。因此,公共密钥在未压缩格式中长度为65字节(32 * 2 +1),压缩格式为33字节(32 +1)长。
未压缩形式由0x04(类似于DER OCTET STRING tag)加上X坐标的二进制表示的连接加上公共点的y坐标的二进制表示组成。
如果基础场是GF(2 ^ p),那么x和y可以被认为是来自[0,n-1]的元素。它们以通常的方式编码,整数被编码,剩余的空间用于填充正好log2(p)/ 8字节用零填充。
对于GF(2 ^ m),x和y可以被认为是具有系数a_i 0或1的多项式a_0x_0 + ... + a_m-1。它们的二进制表示简单地是系数的串联。
具体细节可在SEC1v2中找到。 (特别是第10页和第11页的 2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion 部分。)
答案 1 :(得分:0)
我一直在寻找答案,并希望在Java中分享我的答案。我的任务是从X509Certificate(网站是正确的)获得密钥大小
方法#1 - 实际计算:
ECPublicKeyImpl ecPublicKey = (ECPublicKeyImpl) certificate.getPublicKey();
int publicKeyLength = (ecPublicKey.getEncodedPublicValue().length - 1) / 2 * 8;
(可以添加第一个字节为0x04的验证)
方法#2 - 从一些"内部提取":
ECParameterSpec spec = ecPublicKey.getParams();
AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance("EC");
algorithmParameters.init(spec);
Provider provider = algorithmParameters.getProvider();
provider.get("KeyPairGenerator.EC KeySize");