小能豆

Create a CSR with specific subject order in go

go

I am trying to create a certificate signing request in go using the crypto lib. The CSR produced by the has the subject as “Subject: C = IN, L = loc, O = Example Org, OU = OU1 + OU = OU2, CN = example.com”. I want to change the order of the subject as “Subject: C = IN,O = Example Org, OU = OU1 + OU = OU2, L = loc, CN = example.com”.

I have produced the CSR using below code.

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "crypto/x509/pkix"
    "encoding/pem"
    "fmt"
    "os"
)

func main() {
    privKey, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    csrTemplate := x509.CertificateRequest{
        Subject: pkix.Name{
            Country:            []string{"IN"},
            Organization:       []string{"Example Org"},
            OrganizationalUnit: []string{"OU1", "OU2"},
            Locality:           []string{"loc"},
            CommonName:         "example.com",
        },
        EmailAddresses: []string{"test@example.com"},
    }

    csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &csrTemplate, privKey)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    csrPem := pem.EncodeToMemory(&pem.Block{
        Type:  "CERTIFICATE REQUEST",
        Bytes: csrBytes,
    })

    fmt.Println(string(csrPem))
}

This code produces CSR with subject as “Subject: C = IN, L = loc, O = Example Org, OU = OU1 + OU = OU2, CN = example.com”. I can generate the CSR with required subject order using openssl below command

openssl req -new -sha256 -key my-private-key.pem -out my-csr1.pem -subj '/C=IN/O=Org/OU=OU1/OU=OU2/L=loc/CN=example.com'

How to do the same in go?


阅读 74

收藏
2023-12-19

共1个答案

小能豆

In Go, you can achieve the desired subject order by manually constructing the pkix.Name structure in the desired order. The pkix.Name structure has a field called ExtraNames, which is a slice of AttributeTypeAndValue structures. You can use this field to specify the order of subject attributes. Here’s an example:

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "crypto/x509/pkix"
    "encoding/pem"
    "fmt"
    "os"
)

func main() {
    privKey, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    csrTemplate := x509.CertificateRequest{
        Subject: pkix.Name{
            ExtraNames: []pkix.AttributeTypeAndValue{
                {Type: oidCountry, Value: "IN"},
                {Type: oidOrganization, Value: "Example Org"},
                {Type: oidOrganizationalUnit, Value: "OU1"},
                {Type: oidOrganizationalUnit, Value: "OU2"},
                {Type: oidLocality, Value: "loc"},
                {Type: oidCommonName, Value: "example.com"},
            },
        },
        EmailAddresses: []string{"test@example.com"},
    }

    csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &csrTemplate, privKey)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    csrPem := pem.EncodeToMemory(&pem.Block{
        Type:  "CERTIFICATE REQUEST",
        Bytes: csrBytes,
    })

    fmt.Println(string(csrPem))
}

// OID constants for subject attributes
var (
    oidCountry            = []int{2, 5, 4, 6}
    oidOrganization       = []int{2, 5, 4, 10}
    oidOrganizationalUnit = []int{2, 5, 4, 11}
    oidLocality           = []int{2, 5, 4, 7}
    oidCommonName         = []int{2, 5, 4, 3}
)

In this example, the ExtraNames slice is populated with AttributeTypeAndValue elements in the order you desire. The oidCountry, oidOrganization, etc., are constants representing the OIDs (Object Identifiers) for the respective attributes. This approach allows you to control the order of the subject attributes in the resulting CSR.

2023-12-19