Golang中RSA的使用

本文介绍了Golang中RSA加密算法的使用,包括如何生成密钥对、加密和解密操作,以及涉及到的相关概念如X.509证书、ASN.1和PKCS标准。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Golang中RSA的使用

一. 什么是RSA

对于经常要和网络通信打交道的程序猿来说,RSA这三个字母一定不会陌生。RSA是一种非对称的加密算法,在公开密钥加密和电子商业中被广泛使用。
RSA的核心就是非对称加密算法。非对称加密需要生成一对密钥对。一个用于公开的公开密钥(publickey),而另一个则是需要私下保存不能泄露的私有密钥(privatekey)。使用其中一个密钥进行加密后的信息,只有通过另一个密钥解密才能还原。
利用这一特性,通常有一下两种运用方式:
①公钥加密,私钥解密——用于加密信息,防止信息泄露
②私钥加密,公钥解密——用于数字签名,进行身份验证

二. 生成密钥对

通过GenerateKey方法我们能生成一个PrivateKey

rsa.GenerateKey(random io.Reader, bits int) (*rsa.PrivateKey, error)

来看看PrivateKey的结构

// A PrivateKey represents an RSA key
type PrivateKey struct {
	PublicKey            // public part.
	D         *big.Int   // private exponent
	Primes    []*big.Int // prime factors of N, has >= 2 elements.

	// Precomputed contains precomputed values that speed up private
	// operations, if available.
	Precomputed PrecomputedValues
}

我们可以看到PrivateKey里组合了PublicKey的信息

// A PublicKey represents the public part of an RSA key.
type PublicKey struct {
	N *big.Int // modulus
	E int      // public exponent
}

当然我们也可以通过openssl来生成密钥对的文件

openssl genrsa 1024 > private-key.pem  // 1024代表密钥长度(单位bit)
openssl rsa -in private-key.pem -pubout -out public-key.pem

通过pem文件读取密钥的处理过程如下

func RSAReadPraviteKey(filePath string) (*rsa.PrivateKey, error) {
	privateKeyData, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, err
	}

	privateKeyBlock, _ := pem.Decode(privateKeyData)
	var pri *rsa.PrivateKey
	pri, parseErr := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
	if parseErr != nil {
		return nil, parseErr
	}

	return pri, nil
}

BEGIN RSA PRIVATE KEY开头的文件(PKCS#1),用x509.ParsePKCS1PrivateKey
BEGIN PRIVATE KEY开头的文件(PKCS#8),用x509.ParsePKCS8PrivateKey

PublicKey的处理方式类似,利用的方法为x509.ParsePKIXPublicKey

三. 加密

func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error)
func Encrypt(msg []byte, public *rsa.PublicKey) []byte {
  // crypto/rand.Reader is a good source of entropy for randomizing the
  // encryption function.
  rng := rand.Reader

  ciphertext, err := EncryptOAEP(sha256.New(), rng, public, msg, nil)
  if err != nil {
      fmt.Fprintf(os.Stderr, "Error from encryption: %s\n", err)
      return
  }

  return ciphertext
}

四. 解密

func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error)
func Decrypt(ciphertext []byte, private *rsa.PrivateKey) []byte {
  // crypto/rand.Reader is a good source of entropy for randomizing the
  // encryption function.
  rng := rand.Reader

  plaintext, err := DecryptOAEP(sha256.New(), rng, private, ciphertext, nil)
  if err != nil {
      fmt.Fprintf(os.Stderr, "Error from decryption: %s\n", err)
      return
  }

  return plaintext
}

注意:加密和解密时使用的hash方法必须一致

五. 相关名词

x.509:X.509是ITU-T标准化部门基于他们之前的ASN.1定义的一套证书标准。X.509证书已应用在包括TLS/SSL在内的众多网络协议里,同时它也用在很多非在线应用场景里,比如电子签名服务。X.509证书里含有公钥、身份信息(比如网络主机名,组织的名称或个体名称等)和签名信息(可以是证书签发机构CA的签名,也可以是自签名)。对于一份经由可信的证书签发机构签名或者可以通过其它方式验证的证书,证书的拥有者就可以用证书及相应的私钥来创建安全的通信,对文档进行数字签名。

ASN.1:ASN.1(Abstract Syntax Notation One) 是一套标准,是描述数据的表示、编码、传输、解码的灵活的记法。它提供了一套正式、无歧义和精确的规则以描述独立于特定计算机硬件的对象结构。

PKCS:The Public-Key Cryptography Standards (PKCS)是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。

OAEP:最优非对称加密填充。RSA加密常用的填充模式有三种:RSA_PKCS1_PADDING, RSA_PKCS1_OAEP_PADDING, RSA_NO_PADDING。每次RSA加密的明文的长度是受RSA填充模式限制的,但是RSA每次加密的块长度就是key length。

PKIX:为了将X.509标准应用到Internet上,建设基于X.509标准的PKI系统,IETF(Internet Engineering Task Force)在1995年成立了PKIX工作组,开始制定各种与Internet相关的PKI标准。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值