OpenSSL和BouncyCastle之间的ECDSA密钥大小差异



我正在使用BouncyCastle在C#中实现192位ECDSA签名。 它是我的客户在文本中指定的。 在我开始在BouncyCastle中实现后,他们向我发送了OpenSSL规范。 现在我在OpenSSL和BouncyCastle之间移动密钥时遇到了问题。 我想我一定错过了什么重点,并请您帮助了解 ECDSA 192 如何在两个库中工作。

规范的第一行是:

openssl ecparam -name secp192r1 -genkey -noout -out priv.pem

生成的 priv.pem 包含一个解码为 97 字节的 Base64 字符串。 当我使用 192 位曲线将该密钥馈送到 BouncyCastle 时,我得到了例外。

ECDomainParameters spec = GetEcdsaCurveParamsForInit();
// D is the Private Key
BigInteger d = new BigInteger(tbSigKeyHex.Text, 16);
ECPrivateKeyParameters sKey = new ECPrivateKeyParameters("ECDSA", d, spec);
ECPublicKeyParameters vKey = GL_ECKeyPairGenerator.GetCorrespondingPublicKey(sKey); // EXCEPT on d > 24byte max value

特定的例外是 EcKeyPairGenerator.cs 行上的 System.InvalidOperationException:

ECPoint q = new FixedPointCombMultiplier((。乘法(EC.G, privKey.D(;

如果我将 Ascii-hex 输入字符串截断为 48 个字节,那么 privKey.D 永远不会超过 24 个字节的最大值,一切正常。 但是现在我的代码与规范不同。

我还注意到 BouncyCastle 制作了 24 个字节的键和 192 位曲线:

AsymmetricCipherKeyPair keyPair = GenerateKeys(192); // bit length selects curve in GL_ECKeyPairGenerator
ECPrivateKeyParameters sKey = (ECPrivateKeyParameters)keyPair.Private;
string szD = sKey.D.ToString(16);
PrintToFeedback(string.Format("Generated Private D Key {0} bytes: {1}", szD.Length/2, szD));
ECPublicKeyParameters vKey = (ECPublicKeyParameters)keyPair.Public;

打印输出:

生成的私钥 D 密钥 24 字节:92e67f4a42c3031349f7e88d082a8e1f122eaee8d8b0823d

当我中断并检查 sKey 时,我没有看到任何看起来像 97 字节数字的东西。 我看到 24 字节如何映射到 192 位,但不是 97。 由于我的客户说OpenSSL是规范,我必须假设这是正确的。 但我有点迷茫。 在他们向我发送OpenSSL规范之前,我已经说服自己ECDSA192使用24字节私钥(和48字节公钥,或多或少(,但是这个97字节的OpenSSL密钥再次使一切陷入怀疑。 我的专长是实时和RFID,而不是加密。

有人可以帮助我了解如何在BouncyCastle中使用OpenSSL 97字节密钥吗? 还是我应该撕毁BouncyCastle并用 OpenSSL.Net 重写?

我在Win10下的Cygwin bash窗口中运行,openssl版本是:

OpenSSL 1.0.2o 2018年3月27

谢谢。

openssl ecparam命令生成的文件priv.pem包含的不仅仅是构成密钥私有部分的字节。特别是,它还包括密钥对的公共部分,以及有关密钥在哪种曲线上的一些信息。当你这样做时,你可以看到这一点

$ openssl ec -in priv.pem -noout -text
read EC key
Private-Key: (192 bit)
priv:
74:6b:13:17:a5:6e:bb:8e:76:b1:65:a2:c2:59:16:
72:36:56:ee:42:b9:91:26:53
pub: 
04:9b:d5:f3:61:6b:06:86:c2:d2:1b:c8:1f:86:ae:
ee:58:8a:ac:b3:04:2b:93:c5:8c:1b:24:6e:90:2d:
9c:aa:69:7e:30:15:86:48:06:97:b6:78:35:a6:48:
46:1a:2c:4e
ASN1 OID: prime192v1

因此,要单独使用私有部分,您必须先将其解压缩。

要获得较低级别的了解,了解priv.pem中确切存储的内容,您可以使用asn1parse应用程序:

$ openssl asn1parse -in priv.pem -dump
0:d=0  hl=2 l=  95 cons: SEQUENCE          
2:d=1  hl=2 l=   1 prim: INTEGER           :01
5:d=1  hl=2 l=  24 prim: OCTET STRING      
0000 - 74 6b 13 17 a5 6e bb 8e-76 b1 65 a2 c2 59 16 72   tk...n..v.e..Y.r
0010 - 36 56 ee 42 b9 91 26 53-                          6V.B..&S
31:d=1  hl=2 l=  10 cons: cont [ 0 ]        
33:d=2  hl=2 l=   8 prim: OBJECT            :prime192v1
43:d=1  hl=2 l=  52 cons: cont [ 1 ]        
45:d=2  hl=2 l=  50 prim: BIT STRING        
0000 - 00 04 9b d5 f3 61 6b 06-86 c2 d2 1b c8 1f 86 ae   .....ak.........
0010 - ee 58 8a ac b3 04 2b 93-c5 8c 1b 24 6e 90 2d 9c   .X....+....$n.-.
0020 - aa 69 7e 30 15 86 48 06-97 b6 78 35 a6 48 46 1a   .i~0..H...x5.HF.
0030 - 2c 4e                                             ,N

或者,如果您使用的是Windows,请尝试此出色的ASN.1编辑器工具。

最新更新