下载证书兼容jks

pull/295/head
v-me-50 2025-06-26 16:51:26 +08:00
parent 91e74557aa
commit 4e8f0cf5e8
4 changed files with 82 additions and 0 deletions

View File

@ -144,6 +144,28 @@ func DownloadCert(c *gin.Context) {
return return
} }
} }
// cert.jks
jksData, err := public.PfxToJks(pfxData, pfxPassword, pfxPassword, "allinssl")
if err == nil && jksData != nil {
jksWriter, err := zipWriter.Create("Tomcat/cert.jks")
if err != nil {
public.FailMsg(c, err.Error())
return
}
if _, err := jksWriter.Write(jksData.Bytes()); err != nil {
public.FailMsg(c, err.Error())
return
}
txtWriter, err := zipWriter.Create("Tomcat/passwd.txt")
if err != nil {
public.FailMsg(c, err.Error())
return
}
if _, err := txtWriter.Write([]byte(pfxPassword)); err != nil {
public.FailMsg(c, err.Error())
return
}
}
// 关闭 zipWriter // 关闭 zipWriter
if err := zipWriter.Close(); err != nil { if err := zipWriter.Close(); err != nil {

View File

@ -1,6 +1,7 @@
package public package public
import ( import (
"bytes"
"crypto" "crypto"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/ed25519" "crypto/ed25519"
@ -12,6 +13,7 @@ import (
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
"github.com/pavlo-v-chernykh/keystore-go/v4"
"software.sslmate.com/src/go-pkcs12" "software.sslmate.com/src/go-pkcs12"
"strings" "strings"
"time" "time"
@ -184,3 +186,55 @@ func PEMToPFX(certPEM, keyPEM, pfxPassword string) ([]byte, error) {
return pfxData, nil return pfxData, nil
} }
// PfxToJks 将PFX格式证书转换为JKS格式
func PfxToJks(pfxData []byte, pfxPassword, jksPassword, alias string) (*bytes.Buffer, error) {
if pfxPassword == "" {
return nil, fmt.Errorf("PFX 密码不能为空")
}
if jksPassword == "" {
jksPassword = pfxPassword
}
if alias == "" {
alias = "mycert"
}
// 解析 PFX提取私钥、证书链
priv, cert, caCerts, err := pkcs12.DecodeChain(pfxData, pfxPassword)
if err != nil {
return nil, fmt.Errorf("解析 PFX 失败: %w", err)
}
// 序列化私钥,兼容多种类型
pkBytes, err := x509.MarshalPKCS8PrivateKey(priv)
if err != nil {
return nil, fmt.Errorf("私钥序列化失败: %w", err)
}
// 构建证书链
certChain := make([]keystore.Certificate, 0, len(caCerts)+1)
certChain = append(certChain, keystore.Certificate{
Type: "X.509",
Content: cert.Raw,
})
for _, c := range caCerts {
certChain = append(certChain, keystore.Certificate{
Type: "X.509",
Content: c.Raw,
})
}
// 创建 JKS 并写入条目
ks := keystore.New()
ks.SetPrivateKeyEntry(alias, keystore.PrivateKeyEntry{
PrivateKey: pkBytes,
CertificateChain: certChain,
}, []byte(jksPassword))
// 写入到 Buffer
var buf bytes.Buffer
if err := ks.Store(&buf, []byte(jksPassword)); err != nil {
return nil, fmt.Errorf("生成 JKS 失败: %w", err)
}
return &buf, nil
}

2
go.mod
View File

@ -27,12 +27,14 @@ require (
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
github.com/mitchellh/go-ps v1.0.0 github.com/mitchellh/go-ps v1.0.0
github.com/mojocn/base64Captcha v1.3.8 github.com/mojocn/base64Captcha v1.3.8
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0
github.com/qiniu/go-sdk/v7 v7.25.3 github.com/qiniu/go-sdk/v7 v7.25.3
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1124 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1124
github.com/volcengine/volcengine-go-sdk v1.1.11 github.com/volcengine/volcengine-go-sdk v1.1.11
golang.org/x/crypto v0.37.0 golang.org/x/crypto v0.37.0
modernc.org/sqlite v1.37.0 modernc.org/sqlite v1.37.0
software.sslmate.com/src/go-pkcs12 v0.5.0
) )
require ( require (

4
go.sum
View File

@ -595,6 +595,8 @@ github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mo
github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0 h1:2nosf3P75OZv2/ZO/9Px5ZgZ5gbKrzA3joN1QMfOGMQ=
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0/go.mod h1:lAVhWwbNaveeJmxrxuSTxMgKpF6DjnuVpn6T8WiBwYQ=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM=
@ -1243,3 +1245,5 @@ rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
software.sslmate.com/src/go-pkcs12 v0.5.0 h1:EC6R394xgENTpZ4RltKydeDUjtlM5drOYIG9c6TVj2M=
software.sslmate.com/src/go-pkcs12 v0.5.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=