我正在使用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日
谢谢。
答案 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工具。