Go语言代码实现数字签名过程

一、数字签名流程图

二、实现场景描述

直接使用百度百科中关于数字签名的应用例子,如下:

假如现在 Alice 向 Bob 传送数字信息,为了保证信息传送的保密性、真实性、完整性和不可否认性,需要对传送的信息进行数字加密和签名,其传送过程为:

1.Alice 准备好要传送的数字信息(明文);

2.Alice 对数字信息进行哈希运算,得到一个信息摘要;

3.Alice 用自己的私钥对信息摘要进行加密得到 Alice 的数字签名,并将其附在数字信息上;

4.Alice 随机产生一个加密密钥,并用此密码对要发送的信息进行加密,形成密文;

5.Alice 用 Bob 的公钥对刚才随机产生的加密密钥进行加密,将加密后的 DES 密钥连同密文一起传送给Bob;

6.Bob 收到 Alice 传送来的密文和加密过的 DES 密钥,先用自己的私钥对加密的 DES 密钥进行解密,得到 Alice随机产生的加密密钥;

7.Bob 然后用随机密钥对收到的密文进行解密,得到明文的数字信息,然后将随机密钥抛弃;

8.Bob 用 Alice 的公钥对 Alice 的数字签名进行解密,得到信息摘要;

9.Bob 用相同的哈希算法对收到的明文再进行一次哈希运算,得到一个新的信息摘要;

10.Bob 将收到的信息摘要和新产生的信息摘要进行比较,如果一致,说明收到的信息没有被修改过。

假定Alice和Bob都已知对方的公钥。

以上过程使用的技术:

1、哈希运算:Go语言可以使用sha256哈希运算包将明文信息运算为256为位的哈希值,该值不可逆且唯一。

2、对称加密:使用DES对称加密对明文进行加密。

3、非对称加密:这里使用RSA非对称加密实现数字签名。

三、实现代码

1、DES对称加密代码如下:

package encryp
 
import (
	"bytes"
	"crypto/des"
	"crypto/cipher"
)
 
func padding(src []byte,blocksize int) []byte {
	n:=len(src)
	padnum:=blocksize-n%blocksize
	pad:=bytes.Repeat([]byte{byte(padnum)},padnum)
	dst:=append(src,pad...)
	return dst
}
 
func unpadding(src []byte) []byte {
	n:=len(src)
	unpadnum:=int(src[n-1])
	dst:=src[:n-unpadnum]
	return dst
}
 
func EncryptDES(src []byte,key []byte) []byte {
	block,_:=des.NewCipher(key)
	src=padding(src,block.BlockSize())
	blockmode:=cipher.NewCBCEncrypter(block,key)
	blockmode.CryptBlocks(src,src)
	return src
}
 
func DecryptDES(src []byte,key []byte) []byte {
	block,_:=des.NewCipher(key)
	blockmode:=cipher.NewCBCDecrypter(block,key)
	blockmode.CryptBlocks(src,src)
	src=unpadding(src)
	return src
}

2、RSA非对称加密代码如下:

package encryp

import (
    "crypto/rand"  
    "crypto/rsa"  
    "crypto/x509"  
    "encoding/pem"  
    "errors"  
)

var privateKey = []byte(`  
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDfw1/P15GQzGGYvNwVmXIGGxea8Pb2wJcF7ZW7tmFdLSjOItn9
kvUsbQgS5yxx+f2sAv1ocxbPTsFdRc6yUTJdeQolDOkEzNP0B8XKm+Lxy4giwwR5
LJQTANkqe4w/d9u129bRhTu/SUzSUIr65zZ/s6TUGQD6QzKY1Y8xS+FoQQIDAQAB
AoGAbSNg7wHomORm0dWDzvEpwTqjl8nh2tZyksyf1I+PC6BEH8613k04UfPYFUg1
0F2rUaOfr7s6q+BwxaqPtz+NPUotMjeVrEmmYM4rrYkrnd0lRiAxmkQUBlLrCBiF
u+bluDkHXF7+TUfJm4AZAvbtR2wO5DUAOZ244FfJueYyZHECQQD+V5/WrgKkBlYy
XhioQBXff7TLCrmMlUziJcQ295kIn8n1GaKzunJkhreoMbiRe0hpIIgPYb9E57tT
/mP/MoYtAkEA4Ti6XiOXgxzV5gcB+fhJyb8PJCVkgP2wg0OQp2DKPp+5xsmRuUXv
720oExv92jv6X65x631VGjDmfJNb99wq5QJBAMSHUKrBqqizfMdOjh7z5fLc6wY5
M0a91rqoFAWlLErNrXAGbwIRf3LN5fvA76z6ZelViczY6sKDjOxKFVqL38ECQG0S
pxdOT2M9BM45GJjxyPJ+qBuOTGU391Mq1pRpCKlZe4QtPHioyTGAAMd4Z/FX2MKb
3in48c0UX5t3VjPsmY0CQQCc1jmEoB83JmTHYByvDpc8kzsD8+GmiPVrausrjj4p
y2DQpGmUic2zqCxl6qXMpBGtFEhrUbKhOiVOJbRNGvWW
-----END RSA PRIVATE KEY-----
`) 

var publicKey = []byte(`  
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfw1/P15GQzGGYvNwVmXIGGxea
8Pb2wJcF7ZW7tmFdLSjOItn9kvUsbQgS5yxx+f2sAv1ocxbPTsFdRc6yUTJdeQol
DOkEzNP0B8XKm+Lxy4giwwR5LJQTANkqe4w/d9u129bRhTu/SUzSUIr65zZ/s6TU
GQD6QzKY1Y8xS+FoQQIDAQAB
-----END PUBLIC KEY-----    
`) 

// 加密  
func RsaEncrypt(origData []byte) ([]byte, error) {  
    //解密pem格式的公钥  
    block, _ := pem.Decode(publicKey)  
    if block == nil {  
        return nil, errors.New("public key error")  
    }  
    // 解析公钥  
    pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)  
    if err != nil {  
        return nil, err  
    }  
    // 类型断言  
    pub := pubInterface.(*rsa.PublicKey)  
    //加密  
    return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)  
}  

// 解密  
func RsaDecrypt(ciphertext []byte) ([]byte, error) {  
    //解密  
    block, _ := pem.Decode(privateKey)  
    if block == nil {  
        return nil, errors.New("private key error!")  
    }  
    //解析PKCS1格式的私钥  
    priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)  
    if err != nil {  
        return nil, err  
    }  
    // 解密  
    return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)  
} 

3、服务器端Alice发送信息代码:

package main 

import (
	"encryp"
	"crypto/sha256"
	 "fmt"  
)


type sgTure struct{
	info []byte   //数字信息(加密)
	sginfo []byte //签名信息 
	randKey string //对称加密的密钥,随机生成
}

func main() {
	//发送的信息,Bob,你欠我的500元钱不用还了
	info:="hello,Bob,don't still owe me 500 yuan money"
	
	//将信息生成信息摘要
	data := []byte(info)
	sat:=sha256.Sum256(data)
	
	//用私钥对摘要进行加密,生成数字签名
	sginfo:=encryp.RsaEncrypt(sat)
	
	//将明文信息用随机密钥进行加密
	randkey=getRandStr()
	info:=encryp.EncryptDES(data,randkey)
	
	//以上信息打包发送给Bob
	sgture:=sgTure{
		info,
		sginfo:sginfo,
		randKey:randkey
	}
	
	sendToBob(sgture)	
}

4、客户端Bob接收信息代码:

func main(){
	//获取Alice发送的信息
	valueAll:=getInfofromAlice()
	
	//使用Bob发送的随机对称密钥进行解密
	data:=encryp.DecryptDES(valueAll.info,valueAll.randKey)
	//将该信息生成哈希摘要
	sat:=sha256.Sum256(data)
	
	//使用Alice的公钥进行解密
	sat1:=encryp.RsaDecrypt(valueAll.sginfo)
	
	//如果哈希摘要相同,获取该信息
	if sat==sat1{
		value:=string(data)
	}
	
}

 

你可能感兴趣的:(Go语言,区块链学习,算法学习)