区块链加/解密:非对称加密

非对称加密:Rsa/ECC

加/解密算法中涉及的库及常用公钥标准


pem: 	实现了PEM数据编码;主要用于TLS密钥和证书
x509: 	x509包解析X.509编码的证书和密钥。
	x509.MarshalPKCS1PrivateKey(PrivateKey)	:将rsa私钥序列化为ASN.1 PKCS#1 DER编码。
	x509.MarshalPKIXPublicKey(&PublicKey)	:将公钥序列化为PKIX格式DER编码
	x509.ParsePKIXPublicKey(block.Bytes)	:解析一个DER编码的公钥。这些公钥一般在以"BEGIN PUBLIC KEY"出现的PEM块中
	x509.ParsePKCS1PrivateKey(block.Bytes)	:解析ASN.1 PKCS#1 DER编码的rsa私钥
rsa: 	实现了PKCS#1规定的RSA加密算法。
	rsa.GenerateKey	使用随机数据生成器random生成一对具有指定字位数的RSA密钥
	rsa.EncryptPKCS1v15(rand.Reader, pubkey, src)
	rsa.DecryptPKCS1v15(rand.Reader, pubkey, src)

PKCS#1:定义RSA公开密钥算法加密和签名机制,主要用于组织PKCS#7中所描述的数字签名和数字信封[22]。
PKCS#3:定义Diffie-Hellman密钥交换协议。
PKCS#6:描述了公钥证书的标准语法,主要描述X.509证书的扩展格式。
PKCS#7:定义一种通用的消息语法,包括数字签名和加密等用于增强的加密机制,PKCS#7与PEM兼容;
PKCS#13:椭圆曲线密码体制标准。
PKCS#15:密码令牌信息格式标准。

Rsa:生成公私钥文件

  • 生成私钥操作流程
    1.使用rsa中GenerateKey方法生成私钥
    2.通过x509标准将得到的rsa私钥序列化为ASN.1的DER编码字符串
    3.将私钥字符串设置到pem格式块中
    4.通过pem将设置好的数据进行编码,并写入磁盘文件中
  • 生成公钥操作流程
    1.从得到的私钥对象中将公钥信息取出
    2.通过x509标准将得到的rsa公钥序列化为ASN.1的DER编码字符串
    3.将公钥字符串设置到pem格式块中
    4.通过pem将设置好的数据进行编码,并写入磁盘文件中

//go语言算法实现
func GeneRsa(blockSize int) error {
	PrivateKey, err := rsa.GenerateKey(rand.Reader, blockSize)
	if err != nil {
		return err
	}

	stream := x509.MarshalPKCS1PrivateKey(PrivateKey)

	block := pem.Block{
		Type:  "RSA PrivateKey",
		Bytes: stream,
	}
	PrivateFile, err := os.Create("PrivateKey.pem")
	if err != nil {
		return err
	}

	err = pem.Encode(PrivateFile, &block)

	PublicKey := PrivateKey.PublicKey

	stream1, err := x509.MarshalPKIXPublicKey(&PublicKey)
	if err != nil {
		return err
	}

	block1 := pem.Block{
		Type:  "RSA PublicKey",
		Bytes: stream1,
	}
	PublicFile, err := os.Create("PublicKey.pem")
	if err != nil {
		return err
	}
	err = pem.Encode(PublicFile, &block1)
	return err
}

Rsa:公钥加密/私钥解密

  • 公钥加密
    1.将公钥取出得到PEM编码的字符串
    2.将得到的字符串进行pem解码
    3.使用x509进行解析公钥
    4.使用Rsa对公钥进行加密
  • 私钥解密
    1.将私钥取出得到PEM编码的字符串
    2.将得到的字符串进行pem解码
    3.使用x509进行解析私钥
    4.对私钥使用rsa进行解密

//公钥加密
func EnRsaPublickey(src []byte, fileName string) ([]byte, error) {
	msg := []byte(" ")
	file, err := os.Open(fileName)
	if err != nil {
		return msg, err
	}
	info, err := file.Stat()
	if err != nil {
		return msg, err
	}
	fileSize := info.Size()
	newPem := make([]byte, fileSize)
	file.Read(newPem)

	block, _ := pem.Decode(newPem)
	pubkey1, _ := x509.ParsePKIXPublicKey(block.Bytes)

	pubkey := pubkey1.(*rsa.PublicKey)
	msg, err = rsa.EncryptPKCS1v15(rand.Reader, pubkey, src)
	if err != nil {
		return msg, err
	}
	return msg, err
}

//私钥解密
func DeRsaPrivtekey(src []byte, fileName string) ([]byte, error) {
	msg := []byte(" ")
	file, err := os.Open(fileName)
	if err != nil {
		return msg, err
	}
	info, err := file.Stat()
	if err != nil {
		return msg, err
	}
	fileSize := info.Size()
	newPem := make([]byte, fileSize)
	file.Read(newPem)

	block, _ := pem.Decode(newPem)
	pubkey, _ := x509.ParsePKCS1PrivateKey(block.Bytes)

	//pubkey := pubkey1.(*rsa.PublicKey)
	msg, err = rsa.DecryptPKCS1v15(rand.Reader, pubkey, src)
	fmt.Println("msg", msg)
	if err != nil {
		return msg, err
	}
	return msg, err
}

ECC:私钥签名/公钥解密

前天在学习ECC椭圆曲线加密时,读取了大量博客,可是没有找到真正实现算法的逻辑代码。
我实现的方式比较简单,大家多尝试编写几次,就能实现自己的代码。我将罗列出所有显示步骤的代码,帮助大家浅显易懂


package main

import (
	"crypto/ecdsa"
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"math/big"
	"strings"

	"crypto/elliptic"
	"crypto/rand"
)

//进行测试
func main() {
	src := []byte(string("少壮不努力,活该你单身23333"))
	//这里是我实验,使用不同消息hash摘要进行验证,不用就好
	//src1 := []byte(string("少壮不努力,老大徒伤悲3344"))
	mysrc := myHash(src)
	//mysrc1 := myHash(src1)

	prk, puk, _ := genePriPubKey()
	mystring := sign(prk, mysrc)

	r, s := getSign(mystring)

	result := verifySign(&r, &s, mysrc, puk)
	fmt.Print(result)

}

//生成公/私钥
func genePriPubKey() (*ecdsa.PrivateKey, ecdsa.PublicKey, error) {

	var err error
	var pubkey ecdsa.PublicKey
	var prikey *ecdsa.PrivateKey
	var curve elliptic.Curve
	
	curve = elliptic.P384()//使用的是P384椭圆曲线,可以尝试其他曲线,结果一样
	prikey, err = ecdsa.GenerateKey(curve, rand.Reader)
	if err != nil {
		return prikey, pubkey, err
	}
	pubkey = prikey.PublicKey

	return prikey, pubkey, err
}

//将消息进行hash摘要;我这里使用的是md5,大家也可以尝试其他hash算法
func myHash(src []byte) []byte {
	myhash := md5.New()
	myhash.Write(src)
	return myhash.Sum(nil)
}

//使用私钥,hash摘要进行签名
func sign(key *ecdsa.PrivateKey, myhash []byte) string {
	r, s, _ := ecdsa.Sign(rand.Reader, key, myhash)//返回一对大整数
	rm, _ := r.MarshalText()//需要将大整数r,s转换成[]byte,才能被string
	sm, _ := s.MarshalText()

	return hex.EncodeToString([]byte(string(rm) + "+" + string(sm)))//编译成hex
}

//获取签名之后的密文,进行解密
func getSign(hexrs string) (rint, sint big.Int) {
	st, _ := hex.DecodeString(hexrs)
	str := strings.Split(string(st), "+")//解码之后的st,由r,s2部分拼接,需要对其拆分,然后逐一解码成大整数
	_ = rint.UnmarshalText([]byte(str[0]))
	//假如rint是指针:error: invalid memory address or nil pointer dereference
	_ = sint.UnmarshalText([]byte(str[1]))

	return
}

//对解密之后的明文,hash,公钥验证
func verifySign(rint, sint *big.Int, myhash []byte, pubkey ecdsa.PublicKey) bool {
	//使用ecdsa.Verify进行验证即可
	result := ecdsa.Verify(&pubkey, myhash, rint, sint)
	return result
}

参考博客

算是进阶,使用gzip实现了缓冲
椭圆曲线加密算法的由来
github-Rsa源码
github-ECC源码

猜你喜欢

转载自blog.csdn.net/qq_36652517/article/details/85955697
今日推荐