Gin-使用JWT的非对称加密算法RSA512签名

Gin-使用JWT的非对称加密算法RSA512签名,第1张

1.RSA非对称加密

RSA非对称加密的是对签名的加密,不是对jwt的头部,荷载加密,头部和荷载用的时base64加密,从jwt官网就可以知道
token是通过拼字符串拼在一起的。
从而得出结论:
1.荷载里面可以放自定义的数据,但是不能放敏感数据。



如上图,就算拿着token到这里,可以看见header,payload,但是左下角显示的时无效的签名Invalid Signature,因为没有放入公钥
输入对应的公钥,就可以看见,完成了校验。从而就可以知道公钥和密钥的使用方式和场景。

2.公钥和密钥

非对称加密,前提需要公钥和密钥,它们是成对出现
一般密钥用来签名,公钥用来校验,这一般是两个文件存放的数据。生成密钥可以使用golang的rsa库,公钥可以直接从密钥中获取。

使用golang的rsa库生成密钥

其实在这里,我们可以选择每次生成新token时都重新生成一堆密钥公钥,然后将公钥发布到需要更新公钥的系统中,也可以始终只用一对公钥密钥。这在分布式的系统中很有帮助。产生钥匙对的系统只用将公钥发布给各个系统即可。因为它们只需要做校验功能。

func CreateKeys() (*rsa.PrivateKey, rsa.PublicKey) {
	privateKey, err := rsa.GenerateKey(rand.Reader, 4096)
	if err != nil {
		panic(err)
	}
	publicKey := privateKey.PublicKey
	return privateKey, publicKey
}

这里我们将已经生成的密钥存入了一个private.key文件

根据文件路径获取密钥
func GetPrivateKey(privateKeyFilePath string) *rsa.PrivateKey {
	file, err := os.Open(filePath)
	if err != nil {
		fmt.Errorf("%v", err)
	}
	pkBytes, err := ioutil.ReadAll(file)
	if err != nil {
		fmt.Errorf("%v", err)
	}
	key, err := jwt.ParseRSAPrivateKeyFromPEM(pkBytes)
	if err != nil {
		fmt.Errorf("cannot parse private key>%v", err)
	}
	return key
}
获取公钥
func GetPublicKeyByPrivateKey(privateKeyFilePath string) *rsa.PublicKey {
	privateKey := GetPrivateKey(filePath)
	publicKey := privateKey.PublicKey
	return &publicKey
}

生成token
func (j *JWT) CreateToken(claims request.CustomClaims) (string, error) {
//选择签名算法,传入荷载
	token := jwt.NewWithClaims(jwt.SigningMethodRS512, claims)
	//获取密钥
	privateKey := GetPrivateKey("./source/keyFile/private.key")
	//签名
	tokenStr, err := token.SignedString(privateKey)
	return tokenStr, err
}
解析token

这里从密钥获取公钥是因为,这是在jwt签名的系统中进行的解析,就无所谓了

// 解析 token
func (j *JWT) ParseToken(tokenString string) (*request.CustomClaims, error) {
	publicKey := GetPublicKeyByPrivateKey("密钥数据文件路径")
	token, err := jwt.ParseWithClaims(tokenString, &request.CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
		return publicKey, nil
	})
	if err != nil {
		if ve, ok := err.(*jwt.ValidationError); ok {
			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				return nil, TokenMalformed
			} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
				// Token is expired
				return nil, TokenExpired
			} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
				return nil, TokenNotValidYet
			} else {
				return nil, TokenInvalid
			}
		}
	}
	if token != nil {
		if claims, ok := token.Claims.(*request.CustomClaims); ok && token.Valid {
			return claims, nil
		}
		return nil, TokenInvalid
	} else {
		return nil, TokenInvalid
	}
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/995798.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存