• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    golang 如何获取pem格式RSA公私钥长度

    因在做license注册机制当中,有对根据本地RSA pem密钥文件判断出RSA的公私密钥长度的需求(即:根据pem内容判断出RSA密钥是1024位或者2048位,或者其他位数等),因此个人通过思考,摸索整理出一个方法,予以记录,备用,分享。

    package main
    import (
    	"crypto/rsa"
    	"crypto/x509"
    	"encoding/pem"
    	"errors"
    	"fmt"
    	"io/ioutil"
    	"os"
    )
    //全局变量
    var privateKey, publicKey []byte
    func init() {
    	var err error
    	publicKey, err = ioutil.ReadFile("public.pem")
    	if err != nil {
    		os.Exit(-1)
    	}
    	privateKey, err = ioutil.ReadFile("private.pem")
    	if err != nil {
    		os.Exit(-1)
    	}
    }
    /**
     * @brief 获取RSA公钥长度
     * @param[in]    PubKey				  RSA公钥
     * @return  成功返回 RSA公钥长度,失败返回error	错误信息
     */
    func GetPubKeyLen(PubKey []byte) (int, error) {
    	if PubKey == nil {
    		return 0, errors.New("input arguments error")
    	}
    	block, _ := pem.Decode(PubKey)
    	if block == nil {
    		return 0, errors.New("public rsaKey error")
    	}
    	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    	if err != nil {
    		return 0, err
    	}
    	pub := pubInterface.(*rsa.PublicKey)
    	return pub.N.BitLen(), nil
    }
    /**
     * @brief 获取RSA私钥长度
     * @param[in]    PriKey				  RSA私钥
     * @return  成功返回 RSA私钥长度,失败返回error	错误信息
     */
    func GetPriKeyLen(PriKey []byte) (int, error) {
    	if PriKey == nil {
    		return 0, errors.New("input arguments error")
    	}
    	block, _ := pem.Decode(PriKey)
    	if block == nil {
    		return 0, errors.New("private rsaKey error!")
    	}
    	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    	if err != nil {
    		return 0, err
    	}
    	return priv.N.BitLen(), nil
    }
    func main() {
    	//获取rsa 公钥长度
    	PubKeyLen, _ := GetPubKeyLen(publicKey)
    	fmt.Println("pbulic key len is ", PubKeyLen)
    	//获取rsa 私钥长度
    	PriKeyLen, _ := GetPriKeyLen(privateKey)
    	fmt.Println("private key len is ", PriKeyLen)
    }

    附录:以下程序是产生RSA公私密钥的程序,附件,方便测试。

    package main
    import (
     "crypto/rand"
     "crypto/rsa"
     "crypto/x509"
     "encoding/pem"
     "flag"
     "log"
     "os"
    )
    func main() {
     var bits int
     flag.IntVar(bits, "b", 1024, "密钥长度,默认为1024位")
     flag.Parse()
     
     if err := GenRsaKey(bits); err != nil {
     log.Fatal("密钥文件生成失败!")
     }
     log.Println("密钥文件生成成功!")
    }
    func GenRsaKey(bits int) error {
     // 生成私钥文件
     privateKey, err := rsa.GenerateKey(rand.Reader, bits)
     if err != nil {
     return err
     }
     derStream := x509.MarshalPKCS1PrivateKey(privateKey)
     block := pem.Block{
     Type: "私钥",
     Bytes: derStream,
     }
     file, err := os.Create("private.pem")
     if err != nil {
     return err
     }
     err = pem.Encode(file, block)
     if err != nil {
     return err
     }
     // 生成公钥文件
     publicKey := privateKey.PublicKey
     derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
     if err != nil {
     return err
     }
     block = pem.Block{
     Type: "公钥",
     Bytes: derPkix,
     }
     file, err = os.Create("public.pem")
     if err != nil {
     return err
     }
     err = pem.Encode(file, block)
     if err != nil {
     return err
     }
     return nil
    }
    

    补充:golang 使用RSA生成公私钥,加密,解密,并使用SHA256进行签名,验证

    话不多说直接上代码:

    package main
    import (
    	"crypto"
    	"crypto/rand"
    	"crypto/rsa"
    	"crypto/sha256"
    	"crypto/x509"
    	"encoding/hex"
    	"encoding/pem"
    	"errors"
    	"fmt"
    )
    func main() {
    	//rsa 密钥文件产生
    	fmt.Println("-------------------------------获取RSA公私钥-----------------------------------------")
    	prvKey, pubKey := GenRsaKey()
    	fmt.Println(string(prvKey))
    	fmt.Println(string(pubKey))
    	fmt.Println("-------------------------------进行签名与验证操作-----------------------------------------")
    	var data = "卧了个槽,这么神奇的吗??!!! ԅ(¯﹃¯ԅ) !!!!!!)"
    	fmt.Println("对消息进行签名操作...")
    	signData := RsaSignWithSha256([]byte(data), prvKey)
    	fmt.Println("消息的签名信息: ", hex.EncodeToString(signData))
    	fmt.Println("\n对签名信息进行验证...")
    	if RsaVerySignWithSha256([]byte(data), signData, pubKey) {
    		fmt.Println("签名信息验证成功,确定是正确私钥签名!!")
    	}
    	fmt.Println("-------------------------------进行加密解密操作-----------------------------------------")
    	ciphertext := RsaEncrypt([]byte(data), pubKey)
    	fmt.Println("公钥加密后的数据:", hex.EncodeToString(ciphertext))
    	sourceData := RsaDecrypt(ciphertext, prvKey)
    	fmt.Println("私钥解密后的数据:", string(sourceData))
    }
    //RSA公钥私钥产生
    func GenRsaKey() (prvkey, pubkey []byte) {
    	// 生成私钥文件
    	privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
    	if err != nil {
    		panic(err)
    	}
    	derStream := x509.MarshalPKCS1PrivateKey(privateKey)
    	block := pem.Block{
    		Type: "RSA PRIVATE KEY",
    		Bytes: derStream,
    	}
    	prvkey = pem.EncodeToMemory(block)
    	publicKey := privateKey.PublicKey
    	derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
    	if err != nil {
    		panic(err)
    	}
    	block = pem.Block{
    		Type: "PUBLIC KEY",
    		Bytes: derPkix,
    	}
    	pubkey = pem.EncodeToMemory(block)
    	return
    }
    //签名
    func RsaSignWithSha256(data []byte, keyBytes []byte) []byte {
    	h := sha256.New()
    	h.Write(data)
    	hashed := h.Sum(nil)
    	block, _ := pem.Decode(keyBytes)
    	if block == nil {
    		panic(errors.New("private key error"))
    	}
    	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    	if err != nil {
    		fmt.Println("ParsePKCS8PrivateKey err", err)
    		panic(err)
    	}
    	signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed)
    	if err != nil {
    		fmt.Printf("Error from signing: %s\n", err)
    		panic(err)
    	}
    	return signature
    }
    //验证
    func RsaVerySignWithSha256(data, signData, keyBytes []byte) bool {
    	block, _ := pem.Decode(keyBytes)
    	if block == nil {
    		panic(errors.New("public key error"))
    	}
    	pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
    	if err != nil {
    		panic(err)
    	}
    	hashed := sha256.Sum256(data)
    	err = rsa.VerifyPKCS1v15(pubKey.(*rsa.PublicKey), crypto.SHA256, hashed[:], signData)
    	if err != nil {
    		panic(err)
    	}
    	return true
    }
    // 公钥加密
    func RsaEncrypt(data, keyBytes []byte) []byte {
    	//解密pem格式的公钥
    	block, _ := pem.Decode(keyBytes)
    	if block == nil {
    		panic(errors.New("public key error"))
    	}
    	// 解析公钥
    	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    	if err != nil {
    		panic(err)
    	}
    	// 类型断言
    	pub := pubInterface.(*rsa.PublicKey)
    	//加密
    	ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, pub, data)
    	if err != nil {
    		panic(err)
    	}
    	return ciphertext
    }
    // 私钥解密
    func RsaDecrypt(ciphertext, keyBytes []byte) []byte {
    	//获取私钥
    	block, _ := pem.Decode(keyBytes)
    	if block == nil {
    		panic(errors.New("private key error!"))
    	}
    	//解析PKCS1格式的私钥
    	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    	if err != nil {
    		panic(err)
    	}
    	// 解密
    	data, err := rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
    	if err != nil {
    		panic(err)
    	}
    	return data
    }
    

    运行结果:

    -------------------------------获取RSA公私钥-----------------------------------------
    -----BEGIN RSA PRIVATE KEY-----
    MIICXAIBAAKBgQCgPwlGJrWqTYaoMkI8jXkEI8ewQ7E57G2Fi91WTXMMK7X6GsT9
    VmnRcq++Rk/VS+4IPBlfWyVRg0NfQDyuKjed21fUPa9AIbpYWHgP/tojyeYC1+Ra
    Xncrt9kLp7nW4FZMJmzwU9hfxIB0nhDQqhJenjdBZuYZfkICfMqyqbVkAwIDAQAB
    AoGAJRcSDXOuPrHdBhdD74ILTaL+eFTis3Z+zxdVbsFUbK+9WhtSFxUmPv1dohvi
    JIuDl9JZSRHurFRGhsh2gxVwc7JXwWfD0DmD8dvdzr8q85Jml9YVZ7uhHFqSO4cY
    I7dlBOd7Uwjnc39E/d+1E/kWVNfKt7opPHgt02zOHLSxkbECQQDS7H3myu3oLOi0
    Slpd1MmmHVOo2cqJ1b3H6E8JtEjmHGswWTYvQNAe4yZ+Kffsp5LUYujedncPKvEj
    4G+iz44bAkEAwn4Bx30FKTri/tybgSnCWKwTGSX479829Xucrm5pYU/3D5/PeJQL
    Ra4YSyg2/hU3ZBrue6CdzYJgGXNGEWhAOQJBALMlOB4A96X+FruidzRA2fBj8j10
    lakSSHl1H0RfwpbnRkcvTm0+AEZrqbL4lGGFRplrVNw2BBN25o8RPeArp0cCQEhu
    kw0PI1fqhVUzJXqh6a4KT4aDHMWAlMAxi/VuSzKhjDo2Yxbd06DcqFF9JZXUou9W
    FFDYTUyW7GEuC/85mwkCQCOEjUQX0C3JCSr6fyZIjpEr+znyc9eFHyBp+533Ur4g
    eFu2ewJ3ufJiUBmEj1rEQku8W7h9DS2rXl10IiSwUAA=
    -----END RSA PRIVATE KEY-----
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgPwlGJrWqTYaoMkI8jXkEI8ew
    Q7E57G2Fi91WTXMMK7X6GsT9VmnRcq++Rk/VS+4IPBlfWyVRg0NfQDyuKjed21fU
    Pa9AIbpYWHgP/tojyeYC1+RaXncrt9kLp7nW4FZMJmzwU9hfxIB0nhDQqhJenjdB
    ZuYZfkICfMqyqbVkAwIDAQAB
    -----END PUBLIC KEY-----
    -------------------------------进行签名与验证操作-----------------------------------------
    对消息进行签名操作...
    消息的签名信息: 24a29efbc27e7b84c3b0eed683af28915381b2a0312f5383143cd2006b804d3a16c2b4750fb1857445b46664b795b6cefd402c5cf25e0f28116b7b50f5c16e80af9f9481def0161c6dac7a5d05c56595b891d84091e444ef4012ba1a0efd5cd2ff17c6dfdc109a2a3349ae2523217706a03042ea16d84fcf7d3dae37ee36d2e8
    对签名信息进行验证...
    签名信息验证成功,确定是正确私钥签名!!
    -------------------------------进行加密解密操作-----------------------------------------
    公钥加密后的数据: 2b34d46a62317f4f5e5c8618671831c0970cef2eeddc0d3aca02e1d5b411a067844e1250a1f69cbb1cbcb0cb1964af85836faa346f9ce9fac2710d4fa18e49ee1c4c73496183952fa95a54dd2d633b115504f0a365bac6d022399059a53f51c474e5e4f0f8eefde61bb85d5d812b67114f5d419c33496acaf11d3d84828733f7
    私钥解密后的数据: 卧了个槽,这么神奇的吗??!!! ԅ(¯﹃¯ԅ) !!!!!!)
    

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

    您可能感兴趣的文章:
    • Go 语言中gin使用gzip压缩遇到的问题
    • go判断文件夹是否存在并创建的实例
    • go 协程返回值处理操作
    • golang实现的文件上传下载小工具
    • Golang 实现复制文件夹同时复制文件
    • golang文件读取-按指定BUFF大小读取方式
    • 使用go读取gzip格式的压缩包的操作
    上一篇:golang 64位linux环境下编译出32位程序操作
    下一篇:golang文件读取-按指定BUFF大小读取方式
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    golang 如何获取pem格式RSA公私钥长度 golang,如何,获取,pem,格式,