Функция pem.Decode

Функция pem.Decode из пакета encoding/pem используется для декодирования данных в формате PEM (Privacy-Enhanced Mail). Она принимает на вход байтовый слайс с PEM-данными и возвращает указатель на структуру pem.Block, содержащую заголовки и декодированное содержимое. Если входные данные не являются корректным PEM-блоком, функция возвращает nil.

Синтаксис

gopem.Decode(data []byte) (*pem.Block, []byte)

Пример

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

gopackage main

import (
  "encoding/pem"
  "fmt"
)

func main() {
  pemData := []byte(`
  -----BEGIN RSA PRIVATE KEY-----
  MIIEpAIBAAKCAQEAu1Zvj...
  -----END RSA PRIVATE KEY-----
  `)

  block, rest := pem.Decode(pemData)
  if block == nil {
    fmt.Println("Failed to decode PEM block")
    return
  }

  fmt.Printf("Type: %s\n", block.Type)
  fmt.Printf("Headers: %v\n", block.Headers)
  fmt.Printf("Data length: %d bytes\n", len(block.Bytes))
  fmt.Printf("Remaining data: %d bytes\n", len(rest))
}

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

go"Type: RSA PRIVATE KEY"
"Headers: map[]"
"Data length: 15 bytes"
"Remaining data: 0 bytes"

Пример

Декодируем PEM-блок с сертификатом, содержащим заголовки:

gopackage main

import (
  "encoding/pem"
  "fmt"
)

func main() {
  pemData := []byte(`
  -----BEGIN CERTIFICATE-----
  Proc-Type: 4,ENCRYPTED
  DEK-Info: DES-EDE3-CBC,1234567890ABCDEF

  MIIBzDCCAVQ...
  -----END CERTIFICATE-----
  `)

  block, _ := pem.Decode(pemData)
  if block == nil {
    fmt.Println("Failed to decode PEM block")
    return
  }

  fmt.Printf("Type: %s\n", block.Type)
  fmt.Printf("Headers: %v\n", block.Headers)
  fmt.Printf("Data length: %d bytes\n", len(block.Bytes))
}

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

go"Type: CERTIFICATE"
"Headers: map[Proc-Type:4,ENCRYPTED DEK-Info:DES-EDE3-CBC,1234567890ABCDEF]"
"Data length: 12 bytes"

Пример

Обработка случая, когда входные данные не являются PEM-блоком:

gopackage main

import (
  "encoding/pem"
  "fmt"
)

func main() {
  invalidData := []byte("This is not a PEM block")

  block, rest := pem.Decode(invalidData)
  if block == nil {
    fmt.Println("No PEM block found")
    fmt.Printf("Remaining data: %s\n", string(rest))
    return
  }

  fmt.Println("PEM block decoded successfully")
}

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

go"No PEM block found"
"Remaining data: This is not a PEM block"

Пример

Декодирование нескольких PEM-блоков из одного входного слайса:

gopackage main

import (
  "encoding/pem"
  "fmt"
)

func main() {
  pemData := []byte(`
  -----BEGIN CERTIFICATE-----
  MIICyDCCAbACCQC...
  -----END CERTIFICATE-----
  -----BEGIN RSA PRIVATE KEY-----
  MIIEowIBAAKCAQEA...
  -----END RSA PRIVATE KEY-----
  `)

  remaining := pemData
  blockCount := 0

  for {
    block, rest := pem.Decode(remaining)
    if block == nil {
      break
    }

    blockCount++
    fmt.Printf("Block %d type: %s\n", blockCount, block.Type)
    fmt.Printf("Data length: %d bytes\n", len(block.Bytes))

    remaining = rest
  }

  fmt.Printf("Total blocks decoded: %d\n", blockCount)
}

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

go"Block 1 type: CERTIFICATE"
"Data length: 15 bytes"
"Block 2 type: RSA PRIVATE KEY"
"Data length: 15 bytes"
"Total blocks decoded: 2"

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

  • функцию pem.Encode,
    которая кодирует структуру PEM-блока в формат PEM
  • функцию pem.EncodeToMemory,
    которая возвращает PEM-кодированные данные в виде байтового слайса
  • функцию x509.ParseCertificate,
    которая парсит X.509 сертификат из байтов
  • функцию x509.ParsePKCS1PrivateKey,
    которая парсит приватный ключ RSA в формате PKCS#1