golang通过RSA算法⽣成token,go从配置⽂件中注⼊密钥⽂件,go从⽂件中读
取密。。。
RSA算法 token⽣成与解析
本⽂演⽰两种⽅式,⼀种是把密钥⽂件放在配置⽂件中,⼀种是把密钥⽂件本⾝放⼊项⽬或者容器中。
下⾯两种的区别在于私钥公钥的初始化, init⽅法,需要哪种取哪种。
1. 通过⽂件读取
⾸先是密钥⽂件(privateKey),放在如config⽬录下。
-----BEGIN RSA PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMu4IDG1XU6a7bXo
4V1jSnbKk9Eum2WguAyq+maCRcP9JoHlE/HmhPOjl91aN5gDHw3pgB7QMMkPkuyY
0aG9UiIo7PbBgjXsNBErprKa8G7GKhDN4B3m8jxEi1NLtCk2H8AEf8H/deGFXCde
fjQx0NcTbJ8STfbsqrLhOq2xzAgMBAAECgYEAg1kZMNOd8IOFxqb7P2o4ZbUh
b1rciL8CS/CleBiAgOgkvtWDcZFOoYQV83sqoxFIIYEuwS88dTZcZb32U5EsdYEx
JvJwAAYnzpch/YAz0llvXSHzZwNfGGvs4qt0d74bFpPfveli82wSKMlykeajP2Ro
RQpOniTYOWrJ01UHdUECQQDt1KTj/Xs5BNmEZAkJVmGekQROADk+ztceAe9UMj/J
s5xECdXVwuFh2Rm62MMQNNoW2Pjz4Y5NqhjRu0MMZnlTAkEA20hZsgA78aqTO7s+
+y/CLgP3Cd7uG/5RkcmjBWq2eXkt6wmazZl0BMYb7vshblnMjFXJwuOmfBJl7rTr
1fg8YQJAEo4Jg0QObgdj1QFc9x6HJTDZLiC0VqMag1vRSTdWZK0fnutJhJDctp6S
dFJe/Y+yCCBLY/OP/50qrIo4k+oWwwJAIn8hTTVoOL6C5xSv9cgvnhmVlYHyp4i8
wFieQs3k4vtDVARwzANmExIvdssfGUMbQMCGOxihKkeirYjcyQ6CQQJAbsbpzCjD
wd9JCogmTu/xYqtL898ek7LeNkhgIY2KhYtlptxlHfzgLBUgiSTNTcD1YWtSSp6u
A5ImxrryDYPmfg==
-
----END RSA PRIVATE KEY-----
处理私钥,⽣成token与解析
package main
import(
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"errors"
"github/golang-jwt/jwt/v4"
"io/ioutil"
"log"
"time"
)
var(
publicKey *rsa.PublicKey
privateKey *rsa.PrivateKey
)
func main(){
token,_:=createToken(privateKey)
println("-------------")
error parse newprintln(token)
println("-------------")
a1,_:=getSubFromToken(token)
println(a1)
}
func init(){
publicKeyByte, err := ioutil.ReadFile("公钥的路径/public.key")
if err !=nil{
log.Println(err.Error())
}
publicKey, err = jwt.ParseRSAPublicKeyFromPEM(publicKeyByte)
privateKeyByte, err := ioutil.ReadFile("私钥的路径/private.key")
if err !=nil{
log.Println(err.Error())
}
privateKey,_= jwt.ParseRSAPrivateKeyFromPEM(privateKeyByte)
}
// createToken ⽣成⼀个RS256验证的Token
// Token⾥⾯包括的值,可以⾃⼰根据情况添加,
func createToken(privateKey *rsa.PrivateKey)(tokenStr string, err error){
expireTime := time.Now().Add(7*24* time.Hour)
var audi = jwt.ClaimStrings{
"zwmgc",
}
var expir = jwt.NewNumericDate(expireTime)
claim := jwt.RegisteredClaims{
Audience: audi,
ExpiresAt: expir,//过期时间
//IssuedAt: time.Now().Unix(),
Issuer:"simba-sdk",// 签名颁发者
Subject:"23258bd202e451a988234c2145d754a",//签名主题
}
// jwt.SigningMethodHS256
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claim)
tokenStr,_= token.SignedString(privateKey)
return
}
// getSubFromToken 获取Token的主题(也可以更改获取其他值)
// 参数tokenStr指的是从客户端传来的待验证Token
// 验证Token过程中,如果Token⽣成过程中,指定了iat与exp参数值,将会⾃动根据时间戳进⾏时间验证func getSubFromToken(tokenStr string)(sub string, err error){
// 基于公钥验证Token合法性
token, err := jwt.Parse(tokenStr,func(token *jwt.Token)(interface{},error){
// 基于JWT的第⼀部分中的alg字段值进⾏⼀次验证
if_, ok := token.Method.(*jwt.SigningMethodRSA);!ok {
return nil, errors.New("验证Token的加密类型错误")
}
return publicKey,nil
})
if err !=nil{
return
}
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims["sub"].(string),nil
}
return"", errors.New("token⽆效或者⽆对应值")
}
2. 通过配置⽂件或者字符串
package main
import(
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"errors"
"github/golang-jwt/jwt/v4"
"io/ioutil"
"log"
"time"
)
var(
publicKey *rsa.PublicKey
privateKey *rsa.PrivateKey
)
func main(){
token,_:=createToken(privateKey)
println("-------------")
println(token)
println("-------------")
a1,_:=getSubFromToken(token)
println(a1)
}
func init(){
// 初始化 public Key
var publicKeyStr ="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLuCAxtV1Omu216OFdY0p2ypPR\n"+ "LptloLgMqvpmgkXD/SaB5RPx5oTzo5fdWjeYAx8N6YAe0DDJD5LsmNGhvVIiKOz2\n"+
"wYI17DQRK6aymvBuxioQzeAd5vI8RBH/B/3XhhVwnXn40MdDQxA3E\n"+
"2yfEk327Kqy4TqtscwIDAQAB"
publicKeyBinary :=make([]byte, base64.StdEncoding.DecodedLen(len(publicKeyStr)))
publicKeyLen,_:= base64.StdEncoding.Decode(publicKeyBinary,[]byte(publicKeyStr))
publicKeyBinary = publicKeyBinary[:publicKeyLen]
pubInterface,_:= x509.ParsePKIXPublicKey(publicKeyBinary)
publicKey = pubInterface.(*rsa.PublicKey)
// 初始化 private Key
var privateKeyStr ="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMu4IDG1XU6a7bXo\n"+ "4V1jSnbKk9Eum2WguAyq+maCRcP9JoHlE/HmhPOjl91aN5gDHw3pgB7QMMkPkuyY\n"+
"0aG9UiIo7PbBgjXsNBErprKa8G7GKhDN4B3m8jxEi1NLtCk2H8AEf8H/deGFXCde\n"+
"fjQx0NDEDcTbJ8STfbsqrLhOq2YEAg1kZMNOd8IOFxqb7P2o4ZbUh\n"+
"b1rciL8CS/CleBiAgOgkvtWDcZFOoYQV83sqoxFIIYEuwS88dTZcZb32U5EsdYEx\n"+
"JvJwAAYnzpch/YAz0llvXSHzZwNfGGvs4qt0d74bFpPfveli82wSKMlykeajP2Ro\n"+
"RQpOniTYOWrJ01UHdUECQQDt1KTj/Xs5BNmEZAkJVmGekQROADk+ztceAe9UMj/J\n"+
"s5xECdXVwuFh2Rm62MMQNNoW2Pjz4Y5NqhjRu0MMZnlTAkEA20hZsgA78aqTO7s+\n"+
"+y/CLgP3Cd7uG/5RkcmjBWq2eXkt6wmazZl0BMYb7vshblnMjFXJwuOmfBJl7rTr\n"+
"1fg8YQJAEo4Jg0QObgdj1QFc9x6HJTDZLiC0VqMag1vRSTdWZK0fnutJhJDctp6S\n"+
"dFJe/Y+yCCBLY/OP/50qrIo4k+oWwwJAIn8hTTVoOL6C5xSv9cgvnhmVlYHyp4i8\n"+
"wFieQs3k4vtDVARwzANmExIvdssfGUMbQMCGOxihKkeirYjcyQ6CQQJAbsbpzCjD\n"+
"wd9JCogmTu/xYqtL898ek7LeNkhgIY2KhYtlptxlHfzgLBUgiSTNTcD1YWtSSp6u\n"+
"A5ImxrryDYPmfg=="
privateKeyBinary :=make([]byte, base64.StdEncoding.DecodedLen(len(privateKeyStr)))
privateKeyLen,_:= base64.StdEncoding.Decode(privateKeyBinary,[]byte(privateKeyStr))
privateKeyBinary = privateKeyBinary[:privateKeyLen]
privateInterface,_:= x509.ParsePKCS8PrivateKey(privateKeyBinary)
privateKey = privateInterface.(*rsa.PrivateKey)
}
/
/ createToken ⽣成⼀个RS256验证的Token
// Token⾥⾯包括的值,可以⾃⼰根据情况添加,
func createToken(privateKey *rsa.PrivateKey)(tokenStr string, err error){
expireTime := time.Now().Add(7*24* time.Hour)
var audi = jwt.ClaimStrings{
"zwmgc",
}
var expir = jwt.NewNumericDate(expireTime)
claim := jwt.RegisteredClaims{
Audience: audi,
ExpiresAt: expir,//过期时间
/
/IssuedAt: time.Now().Unix(),
Issuer:"simba-sdk",// 签名颁发者
Subject:"23258bd202e451a988234c2145d754a",//签名主题
}
// jwt.SigningMethodHS256
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claim)
tokenStr,_= token.SignedString(privateKey)
return
}
// getSubFromToken 获取Token的主题(也可以更改获取其他值)
// 参数tokenStr指的是从客户端传来的待验证Token
/
/ 验证Token过程中,如果Token⽣成过程中,指定了iat与exp参数值,将会⾃动根据时间戳进⾏时间验证func getSubFromToken(tokenStr string)(sub string, err error){
// 基于公钥验证Token合法性
token, err := jwt.Parse(tokenStr,func(token *jwt.Token)(interface{},error){
// 基于JWT的第⼀部分中的alg字段值进⾏⼀次验证
if_, ok := token.Method.(*jwt.SigningMethodRSA);!ok {
return nil, errors.New("验证Token的加密类型错误")
}
return publicKey,nil
})
if err !=nil{
return
}
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims["sub"].(string),nil
}
return"", errors.New("token⽆效或者⽆对应值")
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论