Независимо от того, какой код использует jwt.io, это необязательно fr agile.
При использовании PKCS8 для 'E C' (стиль X9.62, ECDSA и / или ECDH и / или связанный ) закрытый ключ, часть, зависящая от алгоритма, использует структуру, определенную приложением C .4 к SEC1 из https://secg.org:
ECPrivateKey ::= SEQUENCE {
version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
privateKey OCTET STRING,
parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL,
publicKey [1] BIT STRING OPTIONAL
}
Как видите, третье и четвертые элементы необязательны. Когда OpenSSL записывает эту структуру, он пропускает третий элемент (параметры), потому что он избыточен с AlgorithmIdentifier внешнего PKCS8, но включает четвертый элемент (publicKey), потому что, хотя технически избыточный, он может быть полезен.
BouncyCastle в Java включает оба, в то время как стандартный провайдер (Oracle / OpenJDK) SunE C не включает ни одного. Сравните https://crypto.stackexchange.com/questions/80275/converting-raw-ecc-private-key-into-asn-1-der-encoded-key/#80290 с моим комментарием. Похоже, что какой бы код ни был запущен jwt.io - он не говорит, и я не пытался выяснить - закодирован для анализа файлов закрытого ключа E C, предполагая, что OpenSSL использует только комбинацию и ничего больше, и, следовательно, не работает ни в формате Bouncy, ни в формате SunE C.
Преобразование формата SunE C в OpenSSL - это небольшая работа - вам действительно нужно выполнить скалярное умножение dG, хотя с Bouncy это не так уж сложно. OTOH, поскольку у вас есть Bouncy, преобразовать формат Bouncy в OpenSSL, просто исключив параметры из структуры SEC1, довольно просто:
//nopackage
import java.io.OutputStreamWriter;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.sec.ECPrivateKey;
import org.bouncycastle.openssl.PKCS8Generator;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.openssl.jcajce.JcaPKCS8Generator;
import org.bouncycastle.util.io.pem.PemObject;
public class SO61676744ECKeyNoParam {
public static void main (String[] args) throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
JcaPEMWriter wr = new JcaPEMWriter(new OutputStreamWriter(System.out));
KeyPairGenerator gen = KeyPairGenerator.getInstance("EC","BC");
gen.initialize(new ECGenParameterSpec("secp256r1"));
KeyPair key = gen.generateKeyPair();
PrivateKeyInfo badp8 = PrivateKeyInfo.getInstance(key.getPrivate().getEncoded());
ECPrivateKey badsec = ECPrivateKey.getInstance(badp8.parsePrivateKey());
ECPrivateKey goodsec = new ECPrivateKey(256, badsec.getKey(), badsec.getPublicKey(), null);
PrivateKeyInfo goodp8 = new PrivateKeyInfo(badp8.getPrivateKeyAlgorithm(), goodsec);
wr.writeObject(new PemObject("PRIVATE KEY", goodp8.getEncoded()));
wr.writeObject(key.getPublic());
wr.close();
}
}