Files
mesh-drop/internal/security/cert.go
2026-02-05 03:39:21 +08:00

82 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package security
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"net"
"os"
"time"
)
// EnsureCertificates 检查证书和密钥文件是否存在。
// 如果不存在,则生成新的自签名证书和密钥。
func EnsureCertificates(certPath, keyPath string) error {
if _, err := os.Stat(certPath); err == nil {
if _, err := os.Stat(keyPath); err == nil {
return nil
}
}
return generateSelfSignedCert(certPath, keyPath)
}
func generateSelfSignedCert(certPath, keyPath string) error {
// 生成私钥
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return err
}
// 创建证书模板
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
Organization: []string{"MeshDrop"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
// 将 IP 地址添加到 SAN主题备用名称用于本地发现
// 添加常见的本地接口 IP 地址和 localhost
template.IPAddresses = []net.IP{net.ParseIP("127.0.0.1")}
// 在实际的动态环境中,我们可能希望添加所有当前接口的 IP 地址
// 实际上,在客户端跳过 IP 验证对于本地 P2P 来说是很常见的。
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
return err
}
// 写入证书文件
certOut, err := os.Create(certPath)
if err != nil {
return err
}
defer certOut.Close()
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
return err
}
// 写入密钥文件
keyOut, err := os.Create(keyPath)
if err != nil {
return err
}
defer keyOut.Close()
if err := pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}); err != nil {
return err
}
return nil
}