Повторно сгенерируйте новые сертификаты x509 с обновленным CommonName - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть закодированный сертификат x509, и я хочу обновить CommonName (иначе имя субъекта или хоста).

Вот код, который я до сих пор (упрощенно):

import (
    "crypto/tls",   
    "crypto/x509"
)

...

// parses a public/private key pair from a pair of PEM encoded data
c, _ := tls.X509KeyPair(certPEMBlock, keyPEMBlock)

// parse into a x509 cert object
cert, _ := x509.ParseCertificate(c.Certificate[0])

// I want to modify the Subject here

// I want to encode it back to PEM encoded data of type []bytes

...

Любая идея, как обновить предмет и закодировать его обратно в PEM-кодированные данные типа [] байтов?

1 Ответ

1 голос
/ 19 февраля 2020

Вы можете создать новый сертификат с кодом, который выглядит следующим образом. Для этого вам понадобится секретный ключ CA:

func GenerateCertificate(ca *x509.Certificate, caKey crypto.PrivateKey, req x509.CertificateRequest, durYear, durMonth int, keyUsage x509.KeyUsage, extKeyUsage []x509.ExtKeyUsage, rsaKeySize int) (certificate, key *pem.Block, err error) {

    cert := &x509.Certificate{
        Version:         req.Version,
        SerialNumber:    RandomBigInt(),
        Subject:         req.Subject,
        Extensions:      req.Extensions,
        ExtraExtensions: req.ExtraExtensions,
        DNSNames:        req.DNSNames,
        EmailAddresses:  req.EmailAddresses,
        IPAddresses:     req.IPAddresses,
        URIs:            req.URIs,
        NotBefore:       time.Now(),
        NotAfter:        time.Now().AddDate(durYear, durMonth, 0),
        ExtKeyUsage:     extKeyUsage,
        KeyUsage:        keyUsage,
    }
    priv, _ := rsa.GenerateKey(rand.Reader, rsaKeySize)
    pub := &priv.PublicKey

    var data []byte
    data, err = x509.CreateCertificate(rand.Reader, cert, ca, pub, caKey)
    if err != nil {
        return
    }
    // Public key
    certificate = &pem.Block{Type: "CERTIFICATE", Bytes: data}
    // Private key
    key = &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}
    return
}

Используйте его как:

    subject := pkix.Name{CommonName:"name"}
    cert, certKey, err := GenerateCertificate(caCert, key, x509.CertificateRequest{Subject: subject}, 1, 0, x509.KeyUsageDigitalSignature,
        []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, 2048)

Вам необходимо выяснить использование ключа, использование ext ключа и т. Д. c , или скопируйте их из старого сертификата. Вы можете инициализировать запрос сертификата, переданный в GenerateCertificate, из старого имеющегося у вас сертификата.

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

func GenerateCA(subject pkix.Name, duryear, durmonth int, rsaKeySize int) (certificate, key *pem.Block, err error) {
    ca := &x509.Certificate{
        SerialNumber:          RandomBigInt(),
        Subject:               subject,
        NotBefore:             time.Now(),
        NotAfter:              time.Now().AddDate(duryear, durmonth, 0),
        IsCA:                  false, // or true?
        ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
        KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
        BasicConstraintsValid: true,
    }

    priv, _ := rsa.GenerateKey(rand.Reader, rsaKeySize)
    pub := &priv.PublicKey
    var data []byte
    data, err = x509.CreateCertificate(rand.Reader, ca, ca, pub, priv)
    if err != nil {
        return
    }

    // Public key
    certificate = &pem.Block{Type: "CERTIFICATE", Bytes: data}
    // Private key
    key = &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}
    return
}
...