Разница в размере ключа ECDSA между OpenSSL и BouncyCastle

Я реализую 192-битную подпись ECDSA на C # с помощью BouncyCastle. Это было указано в тексте моим заказчиком. Они прислали мне спецификацию OpenSSL после того, как я начал внедрять в BouncyCastle. Теперь у меня проблемы с перемещением ключей между OpenSSL и BouncyCastle. Я думаю, что я что-то упускаю из виду, и прошу вашей помощи, чтобы понять, как ECDSA 192 работает в двух библиотеках.

Первая строка спецификации:

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

Полученный файл priv.pem содержит строку Base64, которая декодируется до 97 байт. Когда я передаю этот ключ BouncyCastle с использованием 192-битной кривой, я получаю исключения.

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

Конкретным исключением является System.InvalidOperationException в этой строке EcKeyPairGenerator.cs:

ECPoint q = новый FixedPointCombMultiplier (). Multiply (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, а не в криптографии.

Может ли кто-нибудь помочь мне понять, как использовать байтовый ключ OpenSSL 97 с BouncyCastle? Или мне просто разорвать BouncyCastle и переписать с помощью OpenSSL.Net?

Я работаю в окне Cygwin bash под Win10, версия openssl:

OpenSSL 1.0.2o 27 марта 2018 г.

Спасибо.


person Larry Martin    schedule 21.06.2018    source источник


Ответы (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.

person Reinier Torenbeek    schedule 22.06.2018