Go 使用x509

x509.CreateCertificate 函数概览

x509.CreateCertificate 是一个用于生成X.509证书的函数。其函数原型如下:

func CreateCertificate(rand io.Reader, template \*x509.Certificate, parent \*x509.Certificate, pub any, priv any) ([]byte, error)

  • rand: 随机数生成器,用于生成证书的序列号等。
  • template: 要创建的证书的模板。
  • parent: 签发者的证书。如果要创建的是CA证书,则此处应为自己的证书;如果是非CA,则为上级CA的证书。
  • pub: 被签发者的公钥。
  • priv: 签发者的私钥,用于签署证书。
创建CA证书

要创建一个CA证书,你需要设置template参数的某些字段,特别是IsCA字段和KeyUsage字段。

  1. 生成CA的密钥对:首先,你需要生成CA的密钥对。这通常涉及到创建一个RSA或者ECDSA的公钥和私钥。
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
    log.Fatalf("生成RSA密钥出错: %v", err)
}
pub := &priv.PublicKey

  1. 创建CA证书模板:然后,创建一个x509.Certificate的实例作为CA证书的模板。
ca := &x509.Certificate{
    SerialNumber: big.NewInt(2020),
    Subject: pkix.Name{
        Organization: []string{"Example CA"},
    },
    NotBefore: time.Now(),
    NotAfter:  time.Now().AddDate(10, 0, 0),

    KeyUsage:              x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature,
    ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
    BasicConstraintsValid: true,
    IsCA:                  true,
}

  1. 使用模板和私钥创建CA证书:最后,使用x509.CreateCertificate函数和之前创建的密钥对创建CA证书。
caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, pub, priv)
if err != nil {
    log.Fatalf("创建CA证书失败: %v", err)
}

创建由CA签发的证书

一旦有了CA证书和相应的私钥,你就可以开始创建由该CA签发的证书了。这个过程和创建CA证书类似,不过需要将parent参数设置为CA证书,而template则为你想要创建的证书的模板。

  1. 生成证书的密钥对:和之前一样,首先生成公钥和私钥。
  2. 创建证书模板:创建一个x509.Certificate的实例作为证书的模板。确保IsCA字段为false,除非你想要这个证书作为中间CA。
  3. 使用CA证书和私钥签发新证书:使用x509.CreateCertificate函数、CA的证书、CA的私钥、新证书的公钥来创建新证书。
代码示例

下面是一个完整的示例,展示了如何创建一个CA证书以及一个由该CA签发的证书。

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "crypto/x509/pkix"
    "math/big"
    "time"
    "log"
)

func main() {
    // 为CA生成RSA密钥
    caPriv, \_ := rsa.GenerateKey(rand.Reader, 2048)
    caPub := &caPriv.PublicKey

    // 创建CA证书模板
    ca := &x509.Certificate{
        // ...填入上面提到的字段...
    }

    // 创建CA证书
    caBytes, \_ := x509.CreateCertificate(rand.Reader, ca, ca, caPub, caPriv)

    // 为用户证书生成RSA密钥
    userPriv, \_ := rsa.GenerateKey(rand.Reader, 2048)
    userPub := &userPriv.PublicKey

    // 创建用户证书模板
    user := &x509.Certificate{
        // ...填入相应字段,但不是CA...
    }

    // 使用CA证书和私钥签发用户证书
    userBytes, \_ := x509.CreateCertificate(rand.Reader, user, ca, userPub, caPriv)

    // 这里caBytes和userBytes就是PEM编码的证书
在 Go 语言中,可以使用 crypto/x509 包来操作 X.509 证书和密钥,包括创建公钥和私钥等。 要创建一个新的 X.509 密钥规范,可以使用如下代码: ``` import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" ) func newX509EncodedKeySpec() ([]byte, error) { // 生成 RSA 密钥对 privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, err } // 将私钥编码为 PKCS#1 DER 格式 privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) // 将私钥写入 PEM 格式的文件中 privateKeyPEM := &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: privateKeyBytes, } // 将 PEM 格式的私钥序列化为字节数组 privateKeyPEMBytes := pem.EncodeToMemory(privateKeyPEM) // 将 PKCS#1 DER 格式的私钥序列化为字节数组 privateKeyDERBytes := x509.MarshalPKCS1PrivateKey(privateKey) // 使用私钥生成公钥 publicKey := privateKey.Public() publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) if err != nil { return nil, err } // 将公钥写入 PEM 格式的文件中 publicKeyPEM := &pem.Block{ Type: "PUBLIC KEY", Bytes: publicKeyBytes, } // 将 PEM 格式的公钥序列化为字节数组 publicKeyPEMBytes := pem.EncodeToMemory(publicKeyPEM) // 将 PKIX DER 格式的公钥序列化为字节数组 publicKeyDERBytes, err := x509.MarshalPKIXPublicKey(publicKey) if err != nil { return nil, err } // 返回 X.509 编码的私钥和公钥 return append(privateKeyDERBytes, publicKeyDERBytes...), nil } ``` 这个函数会生成一个 2048 位的 RSA 密钥对,并将私钥和公钥分别编码为 PKCS#1 DER 格式和 PKIX DER 格式,最后将它们合并成一个 X.509 编码的密钥规范,返回字节数组形式的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值