RSA是一种非对称加密算法,它产生了公钥和密钥,公钥加密,私钥解密,或者私钥签名,公钥验签。

下面以Token签发的RSA相关操作探究一下应用。

创建Token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// CreateToken 根据info创建一个token
func CreateToken(info map[string]string, duration time.Duration, sub string) (token Token) {

t := &Token{}
t.Info = info
t.Sub = sub
t.setExp(duration)

payload := t.Payload()

sign := keycenter.Key().Signature(payload) //这里得到了序列化的payload之后,获取签名
t.sign = sign
return *t
}

获取payload签名

1
2
3
4
5
6
7
// Signature 使用该key给一段数据签名
// 签名方法:先对数据取sha256散列 然后rsa私钥加密 加密后再取base64
func (k *RedKey) Signature(data []byte) (signature []byte) {
enc := enCrypto(k.Pri, data) //对data进行签名
signature = []byte(base64.StdEncoding.EncodeToString(enc))//对签名取base64
return
}

用私钥对data进行签名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
type Block struct {
Type string // The type, taken from the preamble (i.e. "RSA PRIVATE KEY").
Headers map[string]string // Optional headers.
Bytes []byte // The decoded bytes of the contents. Typically a DER encoded ASN.1 structure.
}

// enCrypto 加密 先取sha256散列 然后使用rsa私钥加密
func enCrypto(key []byte, data []byte) (b []byte) {
block, _ := pem.Decode(key)
pri, _ := x509.ParsePKCS1PrivateKey(block.Bytes)

h := sha256.New()
h.Write(data)
hash := h.Sum(nil)

b, err := rsa.SignPKCS1v15(rand.Reader, pri, crypto.SHA256, hash)
if err != nil {
log.Fatal(err.Error())
}
return
}

pem是保存私钥的常见格式,这里先对pem格式保存的私钥进行解码,获得block,然后接着进行x509.ParsePKCS1PrivateKey(block.Bytes)获得被封装好的私钥,之后对date序列化获得hash

,把这个hash用私钥签名,获得结果。

验签

1
2
3
4
5
6
7
8
9
func sign(pubkey *rsa.PublicKey, payload, signature []byte) error {

h := sha256.New()
h.Write(payload)
hash := h.Sum(nil)

err := rsa.VerifyPKCS1v15(pubkey, crypto.SHA256, hash, signature)
return err
}

这里把收到的payload给取hash,然后用公钥和hash结果一起放入rsa.VerifyPKCS1v15(pubkey, crypto.SHA256, hash, signature)验证签名。