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

时间:2018-06-21 14:28:34

标签: openssl bouncycastle ecdsa

我正在使用BouncyCastle在C#中实现192位ECDSA签名。它是由我的客户在文本中指定的。在我开始在BouncyCastle中实施之后,他们给我发送了OpenSSL规范。现在,我在OpenSSL和BouncyCastle之间移动密钥时遇到了麻烦。我想我一定错过了要点,并要求您的帮助以了解ECDSA 192在两个库中的工作方式。

规范的第一行是:

  

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

生成的priv.pem包含一个Base64字符串,该字符串解码为97个字节。当我使用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 =新的FixedPointCombMultiplier()。Multiply(ec.G,privKey.D);

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

我还注意到BouncyCastle使用192位曲线制作了24个字节的密钥:

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日

谢谢。

1 个答案:

答案 0 :(得分:1)

priv.pem命令生成的文件openssl ecparam包含的字节不仅仅包含构成密钥私有部分的字节。特别是,它还包括密钥对的公共部分,以及有关密钥位于哪种曲线上的一些信息。您可以在执行此操作时看到它

$ 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 Editor工具。