Функция x509.ParsePKIXPublicKey

Функция x509.ParsePKIXPublicKey из пакета crypto/x509 используется для парсинга публичного ключа, закодированного в формате PKIX (Public Key Infrastructure). На вход она принимает срез байтов []byte, содержащий ASN.1 DER-кодированный публичный ключ, и возвращает интерфейс any и ошибку. Возвращаемый интерфейс содержит конкретный тип ключа, например *rsa.PublicKey, *ecdsa.PublicKey или *ed25519.PublicKey.

При успешном парсинге функция возвращает публичный ключ и nil в качестве ошибки. В случае ошибки парсинга (например, если ключ имеет некорректный формат) возвращается nil и соответствующая ошибка. Важно отметить, что функция не определяет, является ли ключ действительным, она лишь проверяет синтаксическую корректность его структуры.

Синтаксис

gox509.ParsePKIXPublicKey(derBytes []byte) (any, error)

Пример

Давайте распарсим публичный RSA-ключ из DER-кодированных байтов:

gopackage main

import (
  "crypto/rsa"
  "crypto/x509"
  "encoding/base64"
  "fmt"
  "log"
)

func main() {
  // Пример публичного RSA-ключа в формате PKIX (DER), закодированный в base64
  derBase64 := "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCYZM6Yz0q"
  derBytes, err := base64.StdEncoding.DecodeString(derBase64)
  if err != nil {
    log.Fatal(err)
  }

  pubKey, err := x509.ParsePKIXPublicKey(derBytes)
  if err != nil {
    log.Fatal(err)
  }

  rsaPub, ok := pubKey.(*rsa.PublicKey)
  if !ok {
    log.Fatal("Полученный ключ не является RSA")
  }

  fmt.Printf("RSA публичный ключ успешно распарсен, размер: %d бит\n", rsaPub.N.BitLen())
}

Результат выполнения кода:

go"RSA публичный ключ успешно распарсен, размер: 2048 бит"

Пример

Давайте распарсим публичный ECDSA-ключ из DER-кодированных байтов:

gopackage main

import (
  "crypto/ecdsa"
  "crypto/x509"
  "encoding/base64"
  "fmt"
  "log"
)

func main() {
  // Пример публичного ECDSA-ключа в формате PKIX (DER), закодированный в base64
  derBase64 := "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUo1qDjsDp8Xh+Jkf5P7l3Q=="
  derBytes, err := base64.StdEncoding.DecodeString(derBase64)
  if err != nil {
    log.Fatal(err)
  }

  pubKey, err := x509.ParsePKIXPublicKey(derBytes)
  if err != nil {
    log.Fatal(err)
  }

  ecdsaPub, ok := pubKey.(*ecdsa.PublicKey)
  if !ok {
    log.Fatal("Полученный ключ не является ECDSA")
  }

  fmt.Printf("ECDSA публичный ключ успешно распарсен, кривая: %s\n", ecdsaPub.Curve.Params().Name)
}

Результат выполнения кода:

go"ECDSA публичный ключ успешно распарсен, кривая: P-256"

Пример

Давайте попробуем распарсить некорректные данные:

gopackage main

import (
  "crypto/x509"
  "fmt"
  "log"
)

func main() {
  // Некорректные данные для парсинга
  invalidData := []byte("not a valid public key")

  pubKey, err := x509.ParsePKIXPublicKey(invalidData)
  if err != nil {
    fmt.Printf("Ошибка парсинга: %v\n", err)
    return
  }

  fmt.Printf("Распарсенный ключ: %v\n", pubKey)
}

Результат выполнения кода:

go"Ошибка парсинга: asn1: structure error: tags don't match (16 vs {class:0 tag:2 length:1 isCompound:0}) {optional:false explicit:false application:false private:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} AlgorithmIdentifier @2"

Смотрите также

  • функцию x509.MarshalPKIXPublicKey,
    которая выполняет обратное преобразование - сериализует публичный ключ в формат PKIX
  • функцию x509.ParsePKCS1PrivateKey,
    которая парсит приватный RSA-ключ в формате PKCS1
  • функцию x509.ParseCertificate,
    которая парсит X.509 сертификат из DER-кодированных байтов
  • функцию x509.CreateCertificate,
    которая создает новый X.509 сертификат на основе шаблона и ключей