Сообщение об ошибке
x509: unsupported elliptic curve
Воспроизведено на Go 1.26. Парсеры закрытых ключей сообщают о том же ограничении другими словами: ParseECPrivateKey выдаёт «x509: unknown elliptic curve», ParsePKCS8PrivateKey — «x509: failed to parse EC private key embedded in PKCS#8: x509: unknown elliptic curve».
Go crypto/x509 — ParsePKIXPublicKey / ParseCertificate
Что это означает
Структура ключа или сертификата разбирается без ошибок, но OID его кривой не входит в число поддерживаемых стандартной библиотекой Go: crypto/x509 работает только с кривыми NIST P-224, P-256, P-384 и P-521. На практике эта ошибка почти всегда означает одну конкретную кривую — secp256k1, кривую Bitcoin и Ethereum, которую намеренно не включили в стандартную библиотеку: команда Go предоставляет для кривых NIST реализации с постоянным временем выполнения, а всё остальное оставляет сторонним пакетам.
Почему это происходит
Ключевой материал secp256k1 в парсерах стандартной библиотеки
частоКлючи, сгенерированные командой openssl ecparam -name secp256k1 (или экспортированные из инструментов для блокчейна), содержат OID 1.3.132.0.10. Пакет x509 в Go по этому OID определяет, что это ключ EC, но реализации кривой для него не имеет и на этом прекращает разбор.
Brainpool, GOST или другие национальные кривые
иногдаЕвропейские сертификаты на кривых Brainpool и другие кривые не из набора NIST встречаются в некоторых государственных и банковских экосистемах; стандартная библиотека обрабатывает их точно так же, как secp256k1: оболочка разбирается, кривая не поддерживается.
Устаревшие кривые малого размера
редкоСтарый ключевой материал на кривых класса secp160/192 сегодня не только не поддерживается, но и криптографически недостаточно стоек; решение — миграция, а не разбор.
Как исправить
- 1.
Разбирайте secp256k1 специализированной библиотекой
Сами извлеките точку в виде необработанных байтов (или возьмите её из структуры SEC1) и передайте её активно сопровождаемой реализации secp256k1, например из dcrd.
go import ( "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa" ) pub, err := secp256k1.ParsePubKey(pointBytes) // 33/65-byte SEC1 point ok := ecdsa.VerifySignature(...) // via the package's ecdsa subpackage - 2.
Или переведите рабочую нагрузку на P-256
Если кривая secp256k1 в системе ничему не нужна (нет взаимодействия с блокчейнами), сгенерируйте ключи заново на кривой, которую поддерживает стандартная библиотека, и весь набор инструментов упростится.
bash openssl ecparam -name prime256v1 -genkey -noout -out key.pem openssl pkey -in key.pem -pubout -out pub.pem - 3.
Уточните, какую кривую на самом деле использует ключевой материал
Прежде чем браться за библиотеку, прочитайте OID кривой из файла: 1.3.132.0.10 — это secp256k1, 1.2.840.10045.3.1.7 — P-256. Так заодно выявляются файлы с неверной маркировкой, в которых кривая не та, что указана в имени файла или в документации.
bash openssl ec -in key.pem -noout -text | grep -A1 "ASN1 OID" openssl x509 -in cert.pem -noout -text | grep -iA2 "public key algorithm"