Golang如何将PKCS#12格式的JAVA证书转换为JKS格式
Golang如何将PKCS#12格式的JAVA证书转换为JKS格式 我理解大多数人认为JKS不安全且/或已过时,但事实是许多现代软件仍然依赖Java密钥库来运行。
我已经掌握了加载、解码和解析我的CA证书、服务器证书以及PKCS#12证书的代码。
有人有关于如何将.P12文件转换为.JKS的实际示例吗?
最终,我也可以直接使用exec.Command("keytool", ...),但这意味着每次我通过RPM/DEB/APK打包自己的工具时,都需要某个版本的Java作为依赖项以提供keytool,而这里的目标是完全避免使用Java。
func main() {
fmt.Println("hello world")
}
更多关于Golang如何将PKCS#12格式的JAVA证书转换为JKS格式的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang如何将PKCS#12格式的JAVA证书转换为JKS格式的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中实现PKCS#12到JKS的转换需要处理两种不同的密钥库格式。以下是完整的示例代码:
package main
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"os"
"software.sslmate.com/src/go-pkcs12"
"github.com/pavel-v-chernykh/keystore-go/v4"
)
func convertP12ToJKS(p12Path, jksPath, p12Password, jksPassword string) error {
// 读取PKCS#12文件
p12Data, err := ioutil.ReadFile(p12Path)
if err != nil {
return fmt.Errorf("读取P12文件失败: %v", err)
}
// 解码PKCS#12
privateKey, certificate, caCerts, err := pkcs12.Decode(p12Data, p12Password)
if err != nil {
return fmt.Errorf("解码PKCS#12失败: %v", err)
}
// 创建JKS密钥库
ks := keystore.New()
// 将私钥和证书转换为JKS条目
rsaKey, ok := privateKey.(*rsa.PrivateKey)
if !ok {
return fmt.Errorf("不支持的私钥类型")
}
// 创建证书链
certChain := make([]keystore.Certificate, 0, len(caCerts)+1)
certChain = append(certChain, keystore.Certificate{
Type: "X509",
Content: certificate.Raw,
})
for _, caCert := range caCerts {
certChain = append(certChain, keystore.Certificate{
Type: "X509",
Content: caCert.Raw,
})
}
// 创建私钥条目
privateKeyEntry := keystore.PrivateKeyEntry{
CreationTime: keystore.Now(),
PrivateKey: rsaKey,
CertificateChain: certChain,
}
// 将条目添加到密钥库
err = ks.SetPrivateKeyEntry("mykey", privateKeyEntry, []byte(jksPassword))
if err != nil {
return fmt.Errorf("添加私钥条目失败: %v", err)
}
// 保存JKS文件
jksFile, err := os.Create(jksPath)
if err != nil {
return fmt.Errorf("创建JKS文件失败: %v", err)
}
defer jksFile.Close()
err = ks.Store(jksFile, []byte(jksPassword))
if err != nil {
return fmt.Errorf("保存JKS文件失败: %v", err)
}
return nil
}
// 如果需要处理证书链的单独保存
func saveCertificateChain(cert *x509.Certificate, caCerts []*x509.Certificate, basePath string) error {
// 保存主证书
certFile, err := os.Create(basePath + ".crt")
if err != nil {
return err
}
defer certFile.Close()
pem.Encode(certFile, &pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
})
// 保存CA证书链
for i, caCert := range caCerts {
caFile, err := os.Create(fmt.Sprintf("%s-ca-%d.crt", basePath, i))
if err != nil {
return err
}
defer caFile.Close()
pem.Encode(caFile, &pem.Block{
Type: "CERTIFICATE",
Bytes: caCert.Raw,
})
}
return nil
}
func main() {
// 使用示例
err := convertP12ToJKS(
"server.p12",
"server.jks",
"p12password",
"jkspassword",
)
if err != nil {
fmt.Printf("转换失败: %v\n", err)
return
}
fmt.Println("转换成功")
}
需要安装的依赖:
go get software.sslmate.com/src/go-pkcs12
go get github.com/pavel-v-chernykh/keystore-go/v4
这个实现完全避免了Java依赖,直接处理PKCS#12解码和JKS格式生成。keystore-go库提供了完整的JKS格式支持,包括正确的加密和存储格式。

