233-加密之数字签名






加密之数字签名




在说数字签名之前
先说一下 消息认证码 的局限性
A和B都持有密钥
所以不能判断消息是由A生成的还是B生成的


所以可以这样
A持有一个私钥,B持有一个公钥
只有A才可以生成消息,B只能验证消息
这样的话就可以保证消息都是A生成的
这就是数字签名的技术







非对称加密 和 数字签名
假设有A 和 B C D
非对称加密是
B C D持有公钥,进行加密
A持有私钥,可以解密
只有A可以解密

数字签名是
A持有私钥,可以进行加密
B C D持有公钥,可以进行认证







我们来说说 
通过RSA来实现 数字签名

在进行数字签名之前
我们需要通过代码来生成公钥和私钥

func generateRsaKeyPair(bits int) error {

	//1. GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥。
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return err
	}
	fmt.Printf("创建私钥中...\n")

	//2. MarshalPKCS1PrivateKey将rsa私钥序列化为ASN.1 PKCS#1 DER编码。
	derTextPri := x509.MarshalPKCS1PrivateKey(privateKey)

	//3. 创建一个pem格式的block结构,将der编码的字节流写入block
	block := pem.Block{
		Type:    "RSA Private Key",
		Headers: nil,
		Bytes:   derTextPri,
	}

	file1, err := os.Create("rsaPrivateKey.pem")
	if err != nil {
		return err
	}

	defer file1.Close()

	//4. 使用pem的Encode方法,将block写入磁盘文件中
	err = pem.Encode(file1, &block)

	if err != nil {
		return err
	}

	fmt.Printf("创建公钥中...\n")
	//1. 通过私钥获得公钥
	publicKey := privateKey.PublicKey

	//2. MarshalPKCS1PublicKey将rsa私钥序列化为ASN.1 PKCS#1 DER编码。
	derTextPub := x509.MarshalPKCS1PublicKey(&publicKey)

	//3. 创建一个pem格式的block结构,将der编码的字节流写入block
	blockPub := pem.Block{
		Type:    "RSA Publick Key",
		Headers: nil,
		Bytes:   derTextPub,
	}

	file2, err := os.Create("rsaPublicKey.pem")
	if err != nil {
		return err
	}

	defer file2.Close()

	//4. 使用pem的Encode方法,将block写入磁盘文件中
	err = pem.Encode(file2, &blockPub)
	if err != nil {
		return err
	}

	return nil
}

func main() {
	
	err := generateRsaKeyPair(2048)
	if err != nil {
		fmt.Printf("创建rsa秘钥对失败:%s\n", err)
	}

	fmt.Printf("创建rsa秘钥对成功!")
}








生成了公钥和私钥
然后我们来生成数字签名
然后验证一下

func rsaPubKeyEncrypt(src []byte, fileName string) []byte {

	//1. 从公钥文件读取文件,得到pem编码后的数据
	//os.Open()
	buffer, err := ioutil.ReadFile(fileName)
	if err != nil {
		panic(err)
	}

	//2. 对数据进行解码(Decode)得到Block
	//func Decode(data []byte) (p *Block, rest []byte)
	block, _ := pem.Decode(buffer)

	//3. 得到Block中的Bytes,即DER格式的字节流
	derText := block.Bytes

	//4. 解析字节流,得到公钥
	//parsePKCSPublickKey(der []byte)(public *rsa.PublicKey)

	publicKey, err := x509.ParsePKCS1PublicKey(derText)
	if err != nil {
		panic(err)
	}

	//5. 使用公钥进行加密
	//func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error)

	cipherData, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, src)
	if err != nil {
		panic(err)
	}

	return cipherData
}

func rsaPriKeyDecrypt(cipherData []byte, fileName string) []byte {

	//1. 从私钥文件读取数据,得到pem编码后的数据
	buffer, err := ioutil.ReadFile(fileName)
	if err != nil {
		panic(err)
	}

	//2. 对数据进行解码(Decode)得到Block
	//func Decode(data []byte) (p *Block, rest []byte)
	block, _ := pem.Decode(buffer)

	//3. 得到Block中的Bytes,即DER格式的字节流
	derText := block.Bytes

	//4. 解析字节流,得到公钥
	privateKey, err := x509.ParsePKCS1PrivateKey(derText)
	if err != nil {
		panic(err)
	}

	//5. 使用私钥进行解密
	//func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error)

	plainText, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherData)
	if err != nil {
		panic(err)
	}

	return plainText
}

func main() {

	src := []byte("你好 世界 hello world")

	fmt.Printf("原文:%s\n", src)
	cipherData := rsaPubKeyEncrypt(src, "./rsaPublicKey.pem")
	fmt.Printf("cipherData : %x\n", cipherData)

	plainText := rsaPriKeyDecrypt(cipherData, "./rsaPrivateKey.pem")
	fmt.Printf("plainText : %s\n", plainText)
}









 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值