Golang中Ed25519证书能否用于双向TLS(mTLS)认证?

Golang中Ed25519证书能否用于双向TLS(mTLS)认证? Ed25519 证书能否用于双向 TLS (mTLS) 认证?在使用时,是否有任何需要特别注意的事项或限制?

1 回复

更多关于Golang中Ed25519证书能否用于双向TLS(mTLS)认证?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,Ed25519证书完全可以用于双向TLS(mTLS)认证。Ed25519是一种基于椭圆曲线的高效数字签名算法,在TLS 1.3中得到了很好的支持。

以下是使用Ed25519证书进行mTLS认证的示例代码:

package main

import (
	"crypto/ed25519"
	"crypto/rand"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"fmt"
	"math/big"
	"net"
	"net/http"
	"time"
)

// 生成Ed25519证书
func generateEd25519Cert() (tls.Certificate, *x509.Certificate, error) {
	// 生成Ed25519密钥对
	pubKey, privKey, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		return tls.Certificate{}, nil, err
	}

	// 创建证书模板
	template := &x509.Certificate{
		SerialNumber: big.NewInt(1),
		Subject: pkix.Name{
			Organization: []string{"Test Org"},
		},
		NotBefore:             time.Now(),
		NotAfter:              time.Now().Add(365 * 24 * time.Hour),
		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
		BasicConstraintsValid: true,
		IPAddresses:           []net.IP{net.IPv4(127, 0, 0, 1)},
		DNSNames:              []string{"localhost"},
	}

	// 自签名证书
	certDER, err := x509.CreateCertificate(rand.Reader, template, template, pubKey, privKey)
	if err != nil {
		return tls.Certificate{}, nil, err
	}

	// 解析证书
	cert, err := x509.ParseCertificate(certDER)
	if err != nil {
		return tls.Certificate{}, nil, err
	}

	// 转换为tls.Certificate
	tlsCert := tls.Certificate{
		Certificate: [][]byte{certDER},
		PrivateKey:  privKey,
		Leaf:        cert,
	}

	return tlsCert, cert, nil
}

// 创建mTLS服务器
func createMTLSServer() (*http.Server, error) {
	// 生成服务器证书
	serverCert, _, err := generateEd25519Cert()
	if err != nil {
		return nil, err
	}

	// 生成客户端证书(用于验证客户端)
	clientCert, _, err := generateEd25519Cert()
	if err != nil {
		return nil, err
	}

	// 创建证书池
	certPool := x509.NewCertPool()
	certPool.AddCert(clientCert.Leaf)

	// 配置TLS
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{serverCert},
		ClientAuth:   tls.RequireAndVerifyClientCert,
		ClientCAs:    certPool,
		MinVersion:   tls.VersionTLS13, // TLS 1.3对Ed25519支持更好
	}

	// 创建HTTP服务器
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "mTLS authenticated with Ed25519")
	})

	return &http.Server{
		Addr:      ":8443",
		Handler:   mux,
		TLSConfig: tlsConfig,
	}, nil
}

// 创建mTLS客户端
func createMTLSClient() (*http.Client, error) {
	// 生成客户端证书
	clientCert, _, err := generateEd25519Cert()
	if err != nil {
		return nil, err
	}

	// 生成服务器证书(用于验证服务器)
	serverCert, _, err := generateEd25519Cert()
	if err != nil {
		return nil, err
	}

	// 创建证书池
	certPool := x509.NewCertPool()
	certPool.AddCert(serverCert.Leaf)

	// 配置TLS
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{clientCert},
		RootCAs:      certPool,
		MinVersion:   tls.VersionTLS13,
	}

	// 创建HTTP客户端
	transport := &http.Transport{
		TLSClientConfig: tlsConfig,
	}

	return &http.Client{
		Transport: transport,
	}, nil
}

func main() {
	// 启动服务器
	server, err := createMTLSServer()
	if err != nil {
		panic(err)
	}

	go func() {
		fmt.Println("Starting mTLS server on :8443")
		if err := server.ListenAndServeTLS("", ""); err != nil {
			fmt.Printf("Server error: %v\n", err)
		}
	}()

	// 等待服务器启动
	time.Sleep(2 * time.Second)

	// 创建客户端并发送请求
	client, err := createMTLSClient()
	if err != nil {
		panic(err)
	}

	resp, err := client.Get("https://localhost:8443/")
	if err != nil {
		fmt.Printf("Client request error: %v\n", err)
		return
	}
	defer resp.Body.Close()

	fmt.Printf("Response status: %s\n", resp.Status)
}

需要注意的事项:

  1. TLS版本支持:Ed25519在TLS 1.3中得到了原生支持,建议使用TLS 1.3版本:
tlsConfig := &tls.Config{
    MinVersion: tls.VersionTLS13,
}
  1. 证书扩展密钥用法:需要正确设置证书的扩展密钥用法,同时包含服务器认证和客户端认证:
ExtKeyUsage: []x509.ExtKeyUsage{
    x509.ExtKeyUsageServerAuth, 
    x509.ExtKeyUsageClientAuth
}
  1. 证书验证:在双向认证中,双方都需要配置证书池来验证对方的证书:
// 服务器端验证客户端证书
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs:  clientCertPool,

// 客户端验证服务器证书
RootCAs: serverCertPool,
  1. 性能考虑:Ed25519相比传统RSA算法具有更快的签名验证速度和更短的密钥长度,但某些旧系统可能不支持。

  2. 密钥生成:Ed25519密钥生成使用专门的函数:

pubKey, privKey, err := ed25519.GenerateKey(rand.Reader)

这个示例展示了如何在Go中使用Ed25519证书实现完整的双向TLS认证,包括证书生成、服务器配置和客户端配置。

回到顶部