golang-jwt 的项目地址:Signing Methods - golang-jwt docs
- ECDSA 证书和 RSA 证书有什么区别:
ECDSA(Elliptic Curve Digital Signature Algorithm)证书和RSA(Rivest-Shamir-Adleman)证书是两种不同的公钥加密算法所生成的证书,它们之间有几个主要区别:
加密算法:
- RSA:RSA是一种基于整数因子分解问题的公钥加密算法,其安全性基于大素数的难以因式分解。
- ECDSA:ECDSA是一种基于椭圆曲线离散对数问题的公钥加密算法,其安全性基于椭圆曲线上的离散对数难题。
密钥长度:
- RSA:RSA证书通常使用较长的密钥长度,通常为2048位或更长,以确保安全性。
- ECDSA:相比之下,ECDSA证书使用较短的密钥长度,因为椭圆曲线密码学相比传统RSA加密需要更短的密钥长度来提供相同的安全性。通常,ECDSA证书的密钥长度可以选择256位或更长的长度。
性能:
- ECDSA:由于使用较短的密钥长度和椭圆曲线算法的特性,ECDSA在加密和签名操作上通常比RSA更高效。
- RSA:相比之下,RSA的加密和签名操作通常更耗费计算资源,尤其是在密钥长度较长时。
支持情况:
- RSA:RSA是较早被广泛使用的公钥加密算法之一,因此得到了更广泛的支持,许多加密库和协议都支持RSA证书。
- ECDSA:ECDSA在一些新兴的加密应用中得到了较多的关注,但是并不像RSA那样被广泛支持。然而,随着对RSA密钥长度的要求不断增加,ECDSA在一些情况下被视为更加高效和安全的替代方案。
2.生成ECDSA证书:
要生成ECDSA(Elliptic Curve Digital Signature Algorithm)证书,你可以使用OpenSSL工具。以下是生成ECDSA证书的简单步骤:
生成私钥: 使用以下命令生成ECDSA私钥:
openssl ecparam -genkey -name prime256v1 -out ecdsa-private-key.pem这将生成一个名为
ecdsa-private-key.pem的ECDSA私钥文件。生成CSR(Certificate Signing Request) : 使用以下命令生成CSR文件:
openssl req -new -key ecdsa-private-key.pem -out ecdsa-csr.pem在这一步,你需要填写有关证书请求的信息,包括国家、州、城市等信息。
自签名证书(可选): 如果你想要自签名证书,可以使用以下命令生成自签名证书:
openssl x509 -req -days 365 -in ecdsa-csr.pem -signkey ecdsa-private-key.pem -out ecdsa-certificate.pem这将使用私钥对CSR进行签名,生成一个有效期为365天的自签名ECDSA证书文件
ecdsa-certificate.pem。
3.修改证书内容:
3.1编辑ecdsa-private-key.pem: 删除
-----BEGIN EC PARAMETERS-----
xxxx
-----END EC PARAMETERS-----
最后样子:
3.2加载私钥方法:
func loadECDSAPrivateKey(filename string) (*ecdsa.PrivateKey, error) {
// 读取证书文件内容
pemData, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
// 解析 PEM 数据
block, _ := pem.Decode(pemData)
if block == nil || block.Type != "EC PRIVATE KEY" {
return nil, fmt.Errorf("failed to decode PEM block containing ECDSA private key")
}
// 解析 ECDSA 私钥
privateKey, err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return privateKey, nil
}
3.3加载公钥方法:
func loadECDSAPublicKey(filename string) (*ecdsa.PublicKey, error) {
// 读取证书文件内容
certPEM, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
// 解码 PEM 格式证书
block, _ := pem.Decode(certPEM)
if block == nil {
return nil, fmt.Errorf("failed to decode PEM block")
}
// 解析 X.509 证书
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
}
// 从证书中提取公钥
publicKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
if !ok {
return nil, fmt.Errorf("failed to extract ECDSA public key from certificate")
}
return publicKey, nil
}
3.3生成与验证:
func main() {
key, err := loadECDSAPrivateKey("./ecdsa-private-key.pem")
if err != nil {
println("cccc")
println(err.Error())
}
println(key)
// 创建 JWT 令牌
token := jwt.New(jwt.SigningMethodES256)
// 设置 JWT payload
claims := token.Claims.(jwt.MapClaims)
claims["sub"] = "subject"
claims["exp"] = time.Now().Add(time.Hour * 1).Unix()
// 使用 ECDSA 私钥签署 JWT
tokenString, err := token.SignedString(key)
if err != nil {
fmt.Println("Error signing token:", err)
return
}
fmt.Println("JWT token:", tokenString)
publicKey, err := loadECDSAPublicKey("./ecdsa-certificate.pem")
if err != nil {
println("cccc1111")
println(err.Error())
}
println(publicKey)
// 解析 JWT token
tokenS, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return publicKey, nil
})
if err != nil {
fmt.Println("Error parsing token:", err)
return
}
// 验证 JWT token
if tokenS.Valid {
fmt.Println("JWT token is valid")
claims := tokenS.Claims.(jwt.MapClaims)
fmt.Println("Subject:", claims["sub"])
fmt.Println("Expires At:", time.Unix(int64(claims["exp"].(float64)), 0))
} else {
fmt.Println("JWT token is not valid")
}
}