golang实现RSA2的签名与验签函数
2023-02-18 15:36:57 时间
使用非对称加密算法,实现签名与验签
package tools import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" "errors" ) // RSA2私钥签名 func Rsa2PriSign(signContent string, privateKey string, hash crypto.Hash) string { shaNew := hash.New() shaNew.Write([]byte(signContent)) hashed := shaNew.Sum(nil) priKey, err := ParsePrivateKey(privateKey) if err != nil { return "" } signature, err := rsa.SignPKCS1v15(rand.Reader, priKey, hash, hashed) if err != nil { return "" } return base64.StdEncoding.EncodeToString(signature) } // 解析私钥 func ParsePrivateKey(privateKey string) (*rsa.PrivateKey, error) { block, _ := pem.Decode([]byte(privateKey)) if block == nil { return nil, errors.New("私钥信息错误!") } priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return nil, err } return priKey, nil } // RSA2公钥验证签名 func Rsa2PubCheckSign(signContent, sign, publicKey string, hash crypto.Hash) bool { hashed := sha256.Sum256([]byte(signContent)) pubKey, err := ParsePublicKey(publicKey) if err != nil { return false } sig, _ := base64.StdEncoding.DecodeString(sign) err = rsa.VerifyPKCS1v15(pubKey, hash, hashed[:], sig) if err != nil { return false } return true } // 解析公钥 func ParsePublicKey(publicKey string) (*rsa.PublicKey, error) { block, _ := pem.Decode([]byte(publicKey)) if block == nil { return nil, errors.New("公钥信息错误!") } pubKey, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } return pubKey.(*rsa.PublicKey), nil }
测试用例
package tools import ( "crypto" "log" "testing" ) const ( // 私钥 PRIVATE_KEY = ` -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAvSa9KsScy+ZuFTiPLE7ZwMacmxmA6A8fu0jiPluliLwutgRO TTZp3g9HmW1CuYt+ZoQH9t0JzHHNFu9yCetJdt5TrpQx9bBovTsh8h/ZQOPsyo0p nKqi5G3x1Azvbzs6yTU8voz6xVT90/DVJcd71osTsn+7ajEZccfa35tl5DBdF95t hWeyMz5p6ayFMUEU10HBUYmYTUzi4dvXcZUZvLOIOPMHoCTXcX98EmGqUvsLWpx8 mscaA5llZMg+ZXnT5OH+HW9ncfz7DqXiON3yo1BrNPdmN+Y4SI9dWrADUzGJO6u5 8OwncCphUsYqnlG2jd4n0JhjpA2WGD4c6zqJJQIDAQABAoIBAAOmqMYXj3M8Gmnc cp8HUpqu+rzfrCZOjG1ABeXwPOy7vScURDKnVznLD7W9bylHsQPnjoPMVnEUzUGh E5FvcjaSKglXoPM+GXd1mb0jsjzXaW2rdd8pSAWivaU7Lq/187eIiIihDgIbFt8t ad/VzuUgQBwU7RgqpHQWyHnCdSAHanV6TDDzRssJPdVBVLHOgmiMthSw8OtJiXy7 p8oKVsMiLk/+nNKXBorpx4EhYdB4u+XreMBChLT/AYQfZ6Q9xvAVoRnSaFplvqNw Xlxwo0T5tMZLla4QafZ+fQM9GvDudv2NebHvDbL6zTefthCYDK8utaQpcnm70WBp NFdOuW0CgYEA4EAmFxhdop7T+iLcG4LMXAGhvyEmArtQftsfUKcuYV/vXbsX0pj/ 64WmriVfFhyW+d27ZrDZ0knT9in6zfxER3mAigVvd5SJ2co10HiiIRNfMZKXjc3g pKukPAw0fsrBhp1Cdml649RZnTdl7FaUs6xmWIszQi2fUca8HlF3wBMCgYEA1+5v WTV+rcVh9qhs2y8feuWWkmYDVZMbmgE+V+bo4o/6T7FGGKen1EGWV46GiVBix31p WSfMTOIZ7BEhRMU0GH0TGSM6yqsKF4Qu8jg9fxKt4tEMrPmvw/+VoHN+HLV790hP G5Q+I2zDknCWvoWkEDC3y3O4YPh/Cpif/ubZ6OcCgYAePchlOO33rj+b7fOM6jiw 969eXRQJLkWOtfIlKEaC7zMSitaNmgB5PI7b0UJfcv+RNqu9D4BwcXBaNBMUkD6M /P+unUkI8Ukdy70yHfKPT1N5FfHGN8thqZv+VQ8HQkSS6MY7vcHK06o6H2xpUMvA 5zDuI+eHtytTFd/snsPtbQKBgCFM8TklydqMtTXv9ZG767PtUlJTjzIUVM5kYLP3 tXSzVZwSr8e/m19dmgz4uwDUN9eiHKwWOiilOfAxGBtd+lHIgDiBOWDmDdFgnkjW qY0+WTjAmp7WhufIM9Ah35IX3v1c1m5fZ1HZRTQBTw4k2A9zI/UpbIbv68+7h/ks qvCDAoGAF0jwXqwZu0CJB+ojr6dawYXNalEKH7bMPyItdHK4PqWcftHjYXQthnQC uOeS4tEa3nfahGhp68U9N18L3h3gkkHqIGJvPzAEIjaIeghkQ73RinA/94ZlUBm4 jVGL8OEtfrm3O6ukVFTaiBMXPwAN4e3qfkXuyRepN0DjUthymes= -----END RSA PRIVATE KEY----- ` // 私钥 PUBLIC_KEY = ` -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvSa9KsScy+ZuFTiPLE7Z wMacmxmA6A8fu0jiPluliLwutgROTTZp3g9HmW1CuYt+ZoQH9t0JzHHNFu9yCetJ dt5TrpQx9bBovTsh8h/ZQOPsyo0pnKqi5G3x1Azvbzs6yTU8voz6xVT90/DVJcd7 1osTsn+7ajEZccfa35tl5DBdF95thWeyMz5p6ayFMUEU10HBUYmYTUzi4dvXcZUZ vLOIOPMHoCTXcX98EmGqUvsLWpx8mscaA5llZMg+ZXnT5OH+HW9ncfz7DqXiON3y o1BrNPdmN+Y4SI9dWrADUzGJO6u58OwncCphUsYqnlG2jd4n0JhjpA2WGD4c6zqJ JQIDAQAB -----END PUBLIC KEY----- ` ) func TestRsa2Rsa2PriSign(t *testing.T) { //原内容 str := "F78691A5-2963-42D2-A0C7-3A4F31CF5EB6" //生成签名 sig := Rsa2PriSign(str, PRIVATE_KEY, crypto.SHA256) log.Println(sig) //验证原内容与签名是否一致 res := Rsa2PubCheckSign(str, sig, PUBLIC_KEY, crypto.SHA256) log.Println(res) }
验证成功!
相关文章
- 《痞子衡嵌入式半月刊》 第 61 期
- 痞子衡嵌入式:在i.MXRT启动头FDCB里使能串行NOR Flash的QPI/OPI模式
- 痞子衡嵌入式:MCUXpresso IDE下设置代码编译优化等级的几种方法
- 痞子衡嵌入式:浅析IAR下调试信息输出机制之半主机(Semihosting)
- 痞子衡嵌入式:浅析IAR下调试信息输出机制之硬件UART外设
- 痞子衡嵌入式:聊聊i.MXRT1170双核下不同GPIO组的访问以及中断设计
- 《痞子衡嵌入式半月刊》 第 60 期
- 《痞子衡嵌入式半月刊》 第 59 期
- 痞子衡嵌入式:MCUXpresso IDE下将源码制作成Lib库方法及其与IAR,MDK差异
- 《痞子衡嵌入式半月刊》 第 58 期
- 《痞子衡嵌入式半月刊》 第 57 期
- 《痞子衡嵌入式半月刊》 第 56 期
- 《痞子衡嵌入式半月刊》 第 55 期
- 痞子衡嵌入式:浅谈i.MXRT1xxx系列MCU时钟相关功能引脚的作用
- 痞子衡嵌入式:大话双核i.MXRT1170之在线联合调试双核工程的三种方法(IAR篇)
- 《痞子衡嵌入式半月刊》 第 54 期
- 痞子衡嵌入式:聊聊系统看门狗WDOG1在i.MXRT1xxx系统启动中的应用及影响
- 《痞子衡嵌入式半月刊》 第 53 期
- 痞子衡嵌入式:大话双核i.MXRT1170之单独在线调试从核工程的方法(IAR篇)
- 《痞子衡嵌入式半月刊》 第 52 期