Я пишу тестовый жгут в java для программы, связанной с протоколом ikev2. В рамках этого я должен уметь вычислять подпись ECDSA (в частности, используя кривую NIST P-256).Вычисление подписи ECDSA на Java в соответствии с векторным тестом RFC
RFC 4754 Описывает использование ECDSA в IKEv2 и предоставляет набор тестовых векторов (в том числе для кривой p256, которая мне нужна).
Я пытаюсь запустить значения ECDSA-256 Test Vector (Section 8.1 в RFC) посредством реализации подписи ECDSA Java, используя следующий код:
//"abc" for the input
byte[] input = { 0x61, 0x62, 0x63 };
//Ugly way of getting the ECParameterSpec for the P-256 curve by name as opposed to specifying all the parameters manually.
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec kpgparams = new ECGenParameterSpec("secp256r1");
kpg.initialize(kpgparams);
ECParameterSpec params = ((ECPublicKey) kpg.generateKeyPair().getPublic()).getParams();
//Create the static private key W from the Test Vector
ECPrivateKeySpec static_privates = new ECPrivateKeySpec(new BigInteger("DC51D3866A15BACDE33D96F992FCA99DA7E6EF0934E7097559C27F1614C88A7F", 16), params);
KeyFactory kf = KeyFactory.getInstance("EC");
ECPrivateKey spriv = (ECPrivateKey) kf.generatePrivate(static_privates);
//Perfrom ECDSA signature of the data with SHA-256 as the hash algorithm
Signature dsa = Signature.getInstance("SHA256withECDSA");
dsa.initSign(spriv);
dsa.update(input);
byte[] output = dsa.sign();
System.out.println("Result: " + new BigInteger(1, output).toString(16));
Результат должен быть:
CB28E099 9B9C7715 FD0A80D8 E47A7707 9716CBBF 917DD72E 97566EA1 C066957C 86FA3BB4 E26CAD5B F90B7F81 899256CE 7594BB1E A0C89212 748BFF3B 3D5B0315
Вместо этого я получаю:
30460221 00dd9131 edeb5efd c5e718df c8a7ab2d 5532b85b 7d4c012a e5a4e90c 3b824ab5 d7022100 9a8a2b12 9e10a2ff 7066ff79 89aa73d5 ba37c868 5ec36517 216e2e43 ffa876d7
Я знаю, что разница в длине из-за Java ASN. 1 Кодирование подписи. Тем не менее, остальная часть этого совершенно неправа, и я в тупике, почему.
Любая помощь или совет были бы очень признательны!
PS Я не являюсь экспертом крипто ECDSA или Java, так что, вероятно, глупая ошибка, которую я делаю
успеха! Спасибо за быстрый и очень подробный ответ. Как только я прочитал это, это имело смысл, и все это теперь работает на меня. Огромное спасибо за вашу помощь :-) – PinkyNoBrain
P.S Для тех, кто еще смотрит на это. Я изначально сделал ошибку новобранец, выполнив fsr_k.setBytes (новый BigInteger («9E56F509196784D963D1C0A401510EE7ADA3DCC5DEE04B154BF61AF1D5A6DECE», 16) .toByteArray()) и почти заплакал. При этом дополнительный 0 байт добавляется к массиву байтов, и поэтому вы все равно получаете неправильное значение K :-( – PinkyNoBrain
@PinkyNoBrain Вам нужна функция под названием I2OS (целое число с октетной строкой). Этот метод принимает * два * входа , целочисленная и (ключевая) длина. Он возвращает беззнаковое большое кодирование конца целого числа с байтами '00', добавленными до размера ключа. Теперь у вас есть неподписанная часть, убедитесь, что у вас есть и прописная часть. –