脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - golang 如何获取pem格式RSA公私钥长度

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

2021-03-15 00:57天天water Golang

这篇文章主要介绍了golang 如何获取pem格式RSA公私钥长度操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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公私密钥的程序,附件,方便测试。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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进行签名,验证

话不多说直接上代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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
}

运行结果:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-------------------------------获取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
私钥解密后的数据: 卧了个槽,这么神奇的吗??!!! ԅ(¯﹃¯ԅ) !!!!!!)

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

原文链接:https://water.blog.csdn.net/article/details/79817733

延伸 · 阅读

精彩推荐
  • Golanggolang json.Marshal 特殊html字符被转义的解决方法

    golang json.Marshal 特殊html字符被转义的解决方法

    今天小编就为大家分享一篇golang json.Marshal 特殊html字符被转义的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 ...

    李浩的life12792020-05-27
  • Golanggo语言制作端口扫描器

    go语言制作端口扫描器

    本文给大家分享的是使用go语言编写的TCP端口扫描器,可以选择IP范围,扫描的端口,以及多线程,有需要的小伙伴可以参考下。 ...

    脚本之家3642020-04-25
  • Golanggo日志系统logrus显示文件和行号的操作

    go日志系统logrus显示文件和行号的操作

    这篇文章主要介绍了go日志系统logrus显示文件和行号的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    SmallQinYan12302021-02-02
  • Golanggolang 通过ssh代理连接mysql的操作

    golang 通过ssh代理连接mysql的操作

    这篇文章主要介绍了golang 通过ssh代理连接mysql的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    a165861639710342021-03-08
  • Golanggolang如何使用struct的tag属性的详细介绍

    golang如何使用struct的tag属性的详细介绍

    这篇文章主要介绍了golang如何使用struct的tag属性的详细介绍,从例子说起,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看...

    Go语言中文网11352020-05-21
  • GolangGolang通脉之数据类型详情

    Golang通脉之数据类型详情

    这篇文章主要介绍了Golang通脉之数据类型,在编程语言中标识符就是定义的具有某种意义的词,比如变量名、常量名、函数名等等,Go语言中标识符允许由...

    4272021-11-24
  • Golanggolang的httpserver优雅重启方法详解

    golang的httpserver优雅重启方法详解

    这篇文章主要给大家介绍了关于golang的httpserver优雅重启的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    helight2992020-05-14
  • GolangGolang中Bit数组的实现方式

    Golang中Bit数组的实现方式

    这篇文章主要介绍了Golang中Bit数组的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    天易独尊11682021-06-09