Erste Schritte mit PKI mit Golang ―― 4

1. Personen, die in diesem Artikel behandelt werden

2. Übersicht

In diesem Artikel ** 1. Generieren Sie einen privaten Schlüssel und ein Zertifikat mit Go ** ** 2. Erstellen Sie eine Liste der Zertifikate, die mit Go widerrufen werden können ** ** 3. Erstellen Sie eine Erweiterung für die Ausgabe eines Verteilungspunkts in Go ** ** 4. Erstellen Sie eine Zertifikatsperrliste (CRL) in Go ** ** 5. Überprüfen Sie den Inhalt der Zertifikatsperrliste (CRL) mit OpenSSL ** Machen.

3. Erstellen Sie in Golang ein selbstsigniertes CA-Zertifikat und einen privaten Schlüssel

Erstellen Sie ein "Zertifikat" und einen "privaten Schlüssel" für die selbstsignierte Zertifizierungsstelle, die die Zertifikatsperrliste ausstellt. Eine ausführliche Erklärung finden Sie unter Einführung in PKI mit Golang-2. Behalten Sie den privaten Schlüssel im DER-Format bei, da er beim Erstellen der Zertifikatsperrliste als Argument benötigt wird.


	//PrivateKey of Self Sign CA Certificate
	privateCaKey, err := rsa.GenerateKey(rand.Reader, 2048)
	publicCaKey := privateCaKey.Public()

	//[RFC5280]
	subjectCa := pkix.Name{
		CommonName:         "ca01",
		OrganizationalUnit: []string{"Example Org Unit"},
		Organization:       []string{"Example Org"},
		Country:            []string{"JP"},
	}

	caTpl := &x509.Certificate{
		SerialNumber:          big.NewInt(1),
		Subject:               subjectCa,
		NotAfter:              time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC),
		NotBefore:             time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC),
		IsCA:                  true,
		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
		BasicConstraintsValid: true,
	}

	//Self Sign CA Certificate
	caCertificate, err := x509.CreateCertificate(rand.Reader, caTpl, caTpl, publicCaKey, privateCaKey)


	//Convert to ASN.1 DER encoded form
	derCaCert, err = x509.ParseCertificate(caCertificate)
	if err != nil {
		log.Fatalf("ERROR:%v\n", err)
	}

4. Erstellen Sie eine Zertifikatsperrliste in Golang

Erstellen Sie eine Liste der widerrufenen Zertifikate

	var rcs []pkix.RevokedCertificate
	rc := pkix.RevokedCertificate{
		SerialNumber:   big.NewInt(100),
		RevocationTime: time.Now(),
	}

	rcs = append(rcs, rc)

	rc = pkix.RevokedCertificate{
		SerialNumber:   big.NewInt(108),
		RevocationTime: time.Now(),
	}

	rcs = append(rcs, rc)

Hier widerruft die Seriennummer 100 und 108 Zertifikate.

Ausgebender Verteilungspunkt zu crlExtensions in der Zertifikatsperrliste hinzugefügt

Die x509.RevocationList, die beim Erstellen einer Zertifikatsperrliste in Go verwendet wird, verfügt nicht über ein Feld zum direkten Hinzufügen ausstellender Verteilungspunkte. Sie müssen eine separate Struktur für die Ausgabe eines Verteilungspunkts erstellen und dieser zur Erweiterung hinzufügen. In RFC5280 ist Issuing Distribution Point wie folgt definiert.

   id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }

   IssuingDistributionPoint ::= SEQUENCE {
        distributionPoint          [0] DistributionPointName OPTIONAL,
        onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE,
        onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE,
        onlySomeReasons            [3] ReasonFlags OPTIONAL,
        indirectCRL                [4] BOOLEAN DEFAULT FALSE,
        onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }

   DistributionPointName ::= CHOICE {
        fullName                [0]     GeneralNames,
        nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }

   GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName

   GeneralName ::= CHOICE {
        otherName                       [0]     OtherName,
        rfc822Name                      [1]     IA5String,
        dNSName                         [2]     IA5String,
        x400Address                     [3]     ORAddress,
        directoryName                   [4]     Name,
        ediPartyName                    [5]     EDIPartyName,
        uniformResourceIdentifier       [6]     IA5String,
        iPAddress                       [7]     OCTET STRING,
        registeredID                    [8]     OBJECT IDENTIFIER }

Im Folgenden haben wir issuingDistributionPoint und DistributionPointName als die folgende Go-Struktur definiert.

// RFC5280, 5.2.5
type issuingDistributionPoint struct {
	DistributionPoint          distributionPointName `asn1:"optional,tag:0"`
	OnlyContainsUserCerts      bool                  `asn1:"optional,tag:1"`
	OnlyContainsCACerts        bool                  `asn1:"optional,tag:2"`
	OnlySomeReasons            asn1.BitString        `asn1:"optional,tag:3"`
	IndirectCRL                bool                  `asn1:"optional,tag:4"`
	OnlyContainsAttributeCerts bool                  `asn1:"optional,tag:5"`
}

type distributionPointName struct {
	FullName     []asn1.RawValue  `asn1:"optional,tag:0"`
	RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
}

Der Typ des Felds FullName von DistributionPointName ist GeneralNames. Ich möchte angeben, wo die Zertifikatsperrliste mit uniformResourceIdentifier von GeneralName abgerufen werden soll. Stellen Sie im Typ asn1.RawValue wie folgt ein Class: 2 Kontextspezifisch (wie durch asn1.RawValue definiert) Tag: 6 6. von GeneralName, dh uniformResourceIdentifier Bytes: []byte("http://www.example.com/example.crl") Die Codierung für uniformResourceIdentifier lautet IA5String. Da die Zeichenfolge in dem Bereich, der in der URI für crl verwendet wird, dasselbe Byte für IA5String und UTF8 ist, wird sie direkt als Byte-Array übergeben.

	dp := distributionPointName{
		FullName: []asn1.RawValue{
			{Tag: 6, Class: 2, Bytes: []byte("http://www.example.com/example.crl")},
		},
	}

Legen Sie den in der Erweiterung erstellten IssuingDistributionPoint fest.

        
var oidExtensionIssuingDistributionPoint = []int{2, 5, 29, 28}

	idp := issuingDistributionPoint{
		DistributionPoint: dp,
	}

	v, err := asn1.Marshal(idp)

	cdpExt := pkix.Extension{
		Id:       oidExtensionIssuingDistributionPoint,
		Critical: true,
		Value:    v,
	}

x509.RevocationList Struktureinstellungen

x509.RevocationList Geben Sie den Wert ein, den Sie in der Struktur festlegen möchten.

	crlTpl := &x509.RevocationList{
		SignatureAlgorithm:  x509.SHA256WithRSA,
		RevokedCertificates: rcs,
		Number:              big.NewInt(2),
		ThisUpdate:          time.Now(),
		NextUpdate:          time.Now().Add(24 * time.Hour),
		ExtraExtensions:     []pkix.Extension{cdpExt},
	}

Erstellen Sie eine Zertifikatsperrliste

Stellen Sie eine Zertifikatsperrliste aus

	var derCrl []byte
	derCrl, err = x509.CreateRevocationList(rand.Reader, crlTpl, derCaCert, privateCaKey)
	if err != nil {
		log.Fatalf("ERROR:%v\n", err)
	}

	f, err = os.Create("ca01.crl")
	if err != nil {
		log.Fatalf("ERROR:%v\n", err)
	}

	err = pem.Encode(f, &pem.Block{Type: "X509 CRL", Bytes: derCrl})
	if err != nil {
		log.Fatalf("ERROR:%v\n", err)
	}
	err = f.Close()

5. Überprüfen Sie die Zertifikatsperrliste

Überprüfen Sie die Liste der ausgestellten Zertifikatsperrungen mit Openssl. Es enthält alle gesetzten Elemente.

$ openssl crl -inform pem -in example.crl -text
Certificate Revocation List (CRL):
        Version 2 (0x1)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = JP, O = Example Org, OU = Example Org Unit, CN = ca01
        Last Update: Oct 24 04:16:04 2020 GMT
        Next Update: Oct 25 04:16:04 2020 GMT
        CRL extensions:
            X509v3 Authority Key Identifier:
                keyid:0A:42:8D:9B:23:A9:77:11:FF:FD:0F:CC:58:F4:36:F4:98:06:7F:28

            X509v3 CRL Number:
                2
            X509v3 Issuing Distribution Point: critical
                Full Name:
                  URI:http://www.example.com/example.crl

Revoked Certificates:
    Serial Number: 64
        Revocation Date: Oct 24 04:16:04 2020 GMT
    Serial Number: 6C
        Revocation Date: Oct 24 04:16:04 2020 GMT
    Signature Algorithm: sha256WithRSAEncryption
         6c:0d:23:e8:50:bf:84:ae:10:85:3e:43:28:0f:43:fd:58:cb:
         83:8c:7c:a8:5c:7d:78:71:f1:0c:03:97:43:88:8c:32:02:5c:
         a6:6c:e2:a4:7d:94:56:08:a8:9c:17:95:b4:be:11:bb:65:52:
         43:25:de:c0:d5:d0:df:ac:0f:ca:8c:a7:23:82:19:12:e2:9d:
         49:83:9e:ca:bc:2e:f3:60:79:39:47:cb:ed:17:52:25:9f:42:
         26:9e:1b:67:5f:af:e1:3a:14:67:5f:4f:de:10:c5:32:03:7f:
         40:a0:b6:bc:3f:05:33:73:91:0b:73:4e:f2:3c:be:b0:e4:63:
         e0:d0:81:6e:91:14:d9:04:35:21:3e:22:1e:31:bd:47:40:c9:
         69:f0:e5:57:bc:c3:2c:ae:b8:06:38:35:f1:59:6f:45:2c:45:
         08:2e:63:49:ab:f5:54:0b:54:d2:a8:fc:62:ea:a5:46:62:28:
         a9:89:76:96:cf:47:28:3d:81:c3:e9:fb:ce:54:a8:07:71:6d:
         c6:d8:b7:e7:33:b0:05:df:c4:79:56:e1:99:ed:9f:33:f8:15:
         b9:32:4e:82:4c:0c:a7:a5:23:d4:f7:e1:94:26:2b:e0:55:1a:
         38:f6:72:21:a9:e0:29:06:80:9a:05:e3:43:c2:4a:dd:74:c6:
         d6:79:ec:9d
-----BEGIN X509 CRL-----
MIICKDCCARACAQEwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCSlAxFDASBgNV
BAoTC0V4YW1wbGUgT3JnMRkwFwYDVQQLExBFeGFtcGxlIE9yZyBVbml0MQ0wCwYD
VQQDEwRjYTAxFw0yMDEwMjQwNDE2MDRaFw0yMDEwMjUwNDE2MDRaMCgwEgIBZBcN
MjAxMDI0MDQxNjA0WjASAgFsFw0yMDEwMjQwNDE2MDRaoGUwYzAfBgNVHSMEGDAW
gBQKQo2bI6l3Ef/9D8xY9Db0mAZ/KDAKBgNVHRQEAwIBAjA0BgNVHRwBAf8EKjAo
oCagJIYiaHR0cDovL3d3dy5leGFtcGxlLmNvbS9leGFtcGxlLmNybDANBgkqhkiG
9w0BAQsFAAOCAQEAbA0j6FC/hK4QhT5DKA9D/VjLg4x8qFx9eHHxDAOXQ4iMMgJc
pmzipH2UVgionBeVtL4Ru2VSQyXewNXQ36wPyoynI4IZEuKdSYOeyrwu82B5OUfL
7RdSJZ9CJp4bZ1+v4ToUZ19P3hDFMgN/QKC2vD8FM3ORC3NO8jy+sORj4NCBbpEU
2QQ1IT4iHjG9R0DJafDlV7zDLK64Bjg18VlvRSxFCC5jSav1VAtU0qj8YuqlRmIo
qYl2ls9HKD2Bw+n7zlSoB3Ftxti35zOwBd/EeVbhme2fM/gVuTJOgkwMp6Uj1Pfh
lCYr4FUaOPZyIangKQaAmgXjQ8JK3XTG1nnsnQ==
-----END X509 CRL-----

6. Code

Klicken Sie hier für den Code https://github.com/tardevnull/gopkicookbook4

Recommended Posts

Erste Schritte mit PKI mit Golang ―― 4
1.1 Erste Schritte mit Python
Erste Schritte mit apache2
Erste Schritte mit Python
Erste Schritte mit Django 1
Einführung in die Optimierung
Erste Schritte mit Numpy
Erste Schritte mit Spark
Erste Schritte mit Python
Erste Schritte mit Pydantic
Erste Schritte mit Jython
Erste Schritte mit Django 2
Übersetzen Erste Schritte mit TensorFlow
Einführung in Python-Funktionen
Einführung in Tkinter 2: Button
Erste Schritte mit Go Assembly
Erste Schritte mit Python Django (1)
Erste Schritte mit Python Django (4)
Erste Schritte mit Python Django (3)
Einführung in Python Django (6)
Erste Schritte mit Django mit PyCharm
Erste Schritte mit Python Django (5)
Erste Schritte mit Python Responder v2
Einführung in Git (1) History-Speicher
Erste Schritte mit Sphinx. Generieren Sie Docstring mit Sphinx
Erste Schritte mit Python-Webanwendungen
Erste Schritte mit Python für PHPer-Klassen
Erste Schritte mit Sparse Matrix mit scipy.sparse
Erste Schritte mit Julia für Pythonista
Erste Schritte mit Python Grundlagen von Python
Erste Schritte mit der Cisco Spark REST-API
Beginnend mit USD unter Windows
Erste Schritte mit genetischen Python-Algorithmen
Erste Schritte mit Python 3.8 unter Windows
Erste Schritte mit Python für PHPer-Funktionen
Erste Schritte mit der CPU-Diebstahlzeit
Erste Schritte mit Python3 # 1 Grundkenntnisse erlernen
Erste Schritte mit Python Web Scraping Practice
Erste Schritte mit Python für PHPer-Super Basics
Erste Schritte mit Python Web Scraping Practice
Erste Schritte mit Dynamo von Python Boto
Erste Schritte mit Lisp für Pythonista: Ergänzung
Erste Schritte mit Heroku, Bereitstellen der Flaschen-App
Erste Schritte mit TDD mit Cyber-dojo bei MobPro
Grale fangen an
Erste Schritte mit Python mit 100 Klopfen bei der Sprachverarbeitung
MongoDB-Grundlagen: Erste Schritte mit CRUD mit JAVA
Erste Schritte mit dem Zeichnen mit matplotlib: Schreiben einfacher Funktionen
Erste Schritte mit der japanischen Übersetzung des Keras Sequential-Modells
[Übersetzung] Erste Schritte mit Rust für Python-Programmierer
Django Erste Schritte Teil 2 mit dem Eclipse Plugin (PyDev)
Erste Schritte mit AWS IoT in Python
Erste Schritte mit Pythons Ast-Modul (Verwenden von NodeVisitor)
Materialien zum Lesen, wenn Sie mit Python beginnen
Einstellungen für den Einstieg in MongoDB mit Python