RSA加密解密及制作软件license

1 RSA算法

倘若在加解密信息的过程中,能让加密密钥(公钥)与解密密钥(私钥)不同,即:

  1. 甲要传密信给乙,乙先根据某种算法得出本次与甲通信的公钥与私钥;
  2. 乙将公钥传给甲(公钥可以让任何人知道,即使泄露也没有任何关系);
  3. 甲使用乙传给的公钥加密要发送的信息原文m,发送给乙密文c;
  4. 乙使用自己的私钥解密密文c,得到信息原文m。

就可以很好的克服对称加密算法的弱点,这种新的加密模式被称为“非对称加密算法”。可以观察到,从始至终,私钥一直都在信息接收方乙处,只要乙自己不泄露出去,私钥就没有泄露的可能。

1977年,三位数学家Rivest、Shamir和Adleman设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字首字母命名,叫做RSA算法,RSA算法非常可靠,密钥越长,它就越难破解。

2 生成公钥私钥

openssl生成私钥

openssl genrsa -out rsa_private_key.pem 1024

openssl生成公钥

openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

3 Go实现公钥加密私钥解密

// 公钥加密
func RsaEncrypt(publicKey, originData []byte) ([]byte, error) {
	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, originData)
}

// 私钥解密
func RsaDecrypt(privateKey, cipherData []byte) ([]byte, error) {
	block, _ := pem.Decode(privateKey)
	if block == nil {
		return nil, errors.New("private key error")
	}

	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}

	return rsa.DecryptPKCS1v15(rand.Reader, priv, cipherData)
}

4 Go制作license(私钥签名公钥验证)

如果需要为软件制作一个license,那么公钥加密私钥解密还无法达到目的。而Go官方API不支持私钥加密公钥解密,因此可以采用私钥签名公钥验证的方案。具体步骤如下:

  1. 确定要签名的信息。如授权开始时间、授权结束时间、软件版本等信息。
  2. 生成签名。对要签名的信息计算hash,然后使用私钥对hash结果制作签名。
  3. 生成license。license内容由被签名信息和签名两部分组成。
  4. 验证license。使用公钥验证签名,验证通过则说明被签名信息没有被篡改。签名验证通过后再比对其他信息,例如当前时间是否在授权时间范围内等。
//私钥签名
func RsaSign(privateKey, data []byte) ([]byte, error) {
	h := sha256.New()
	h.Write(data)
	hashed := h.Sum(nil)

	block, _ := pem.Decode(privateKey)
	if block == nil {
		return nil, errors.New("private key error")
	}

	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	return rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, hashed)
}

//公钥验证
func RsaSignVer(publicKey, data, signature []byte) error {
	hashed := sha256.Sum256(data)
	block, _ := pem.Decode(publicKey)
	if block == nil {
		return errors.New("public key error")
	}

	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return err
	}
	// 类型断言
	pub := pubInterface.(*rsa.PublicKey)
	//验证签名
	return rsa.VerifyPKCS1v15(pub, crypto.SHA256, hashed[:], signature)
}
发布了345 篇原创文章 · 获赞 374 · 访问量 89万+

猜你喜欢

转载自blog.csdn.net/u011331383/article/details/88599440