Функция x509.ParseCertificate
Функция x509.ParseCertificate выполняет парсинг DER-кодированного
сертификата X.509 и возвращает указатель на структуру
x509.Certificate. В качестве входного параметра функция
принимает срез байтов []byte, содержащий данные сертификата
в формате DER. В случае успешного разбора возвращается
*x509.Certificate и nil в качестве ошибки.
Если парсинг завершился неудачей, функция возвращает
nil и ошибку с описанием проблемы.
Синтаксис
x509.ParseCertificate(derBytes []byte) (*x509.Certificate, error)
Пример
Давайте разберем простой DER-сертификат и выведем его основные поля:
package main
import (
"crypto/x509"
"encoding/pem"
"fmt"
"log"
)
func main() {
// Пример PEM-сертификата (самоподписанный)
pemCert := `-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKl4mKkqN1ZzMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMjQwMTAxMDAwMDAwWhcNMjUwMTAxMDAwMDAwWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAu1SU1LfVLPHCYZM6YkLFiNmL6Q=="
-----END CERTIFICATE-----`
// Декодируем PEM
block, _ := pem.Decode([]byte(pemCert))
if block == nil {
log.Fatal("failed to parse PEM block")
}
// Парсим сертификат
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
log.Fatal(err)
}
// Выводим информацию о сертификате
fmt.Printf("Subject: %s\n", cert.Subject.CommonName)
fmt.Printf("Issuer: %s\n", cert.Issuer.CommonName)
fmt.Printf("Serial Number: %s\n", cert.SerialNumber.String())
fmt.Printf("Not Before: %s\n", cert.NotBefore)
fmt.Printf("Not After: %s\n", cert.NotAfter)
}
Результат выполнения кода:
"Subject: "
"Issuer: "
"Serial Number: 16993836966523861691"
"Not Before: 2024-01-01 00:00:00 +0000 UTC"
"Not After: 2025-01-01 00:00:00 +0000 UTC"
Пример
Давайте проверим, что функция возвращает ошибку при попытке разобрать некорректные данные:
package main
import (
"crypto/x509"
"fmt"
)
func main() {
// Некорректные данные (не DER)
invalidData := []byte("this is not a certificate")
cert, err := x509.ParseCertificate(invalidData)
if err != nil {
fmt.Printf("Error: %v\n", err)
fmt.Printf("Certificate is nil: %v\n", cert == nil)
}
}
Результат выполнения кода:
"Error: x509: malformed certificate"
"Certificate is nil: true"
Пример
Давайте извлечем открытый ключ из сертификата и проверим его тип:
package main
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"log"
)
func main() {
pemCert := `-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKl4mKkqN1ZzMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMjQwMTAxMDAwMDAwWhcNMjUwMTAxMDAwMDAwWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAu1SU1LfVLPHCYZM6YkLFiNmL6Q=="
-----END CERTIFICATE-----`
block, _ := pem.Decode([]byte(pemCert))
if block == nil {
log.Fatal("failed to parse PEM block")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
log.Fatal(err)
}
// Проверяем тип открытого ключа
switch pub := cert.PublicKey.(type) {
case *rsa.PublicKey:
fmt.Printf("RSA public key with %d bits\n", pub.N.BitLen())
default:
fmt.Printf("Unknown key type: %T\n", pub)
}
}
Результат выполнения кода:
"RSA public key with 1024 bits"
Смотрите также
-
функцию
x509.CreateCertificate,
которая создает новый X.509 сертификат -
функцию
x509.ParsePKCS1PrivateKey,
которая парсит PKCS1 закрытый ключ -
функцию
x509.ParsePKIXPublicKey,
которая парсит открытый ключ в формате PKIX -
функцию
pem.Decode,
которая декодирует PEM-блок для подготовки данных к парсингу