您当前的位置:首页 > 计算机 > 编程开发 > Go语言

GO加密解密RSA番外篇:生成RSA密钥

时间:03-07来源:作者:点击数:

《Go加密解密之RSA》中,说到了RSA密钥的生成问题,例子中的密钥,是通过openssl生成的。其实,通过那篇文章,可以很容易的反向,用Go生成openssl那样的密钥保存在文件中。该番外篇就是做这事。

一、加解密流程

首先回顾一下上篇文章加解密流程:

1、读取密钥(可以写死在一个变量中保存,也可以从一个外部文件读取) 2、通过encoding/pem中的Decode函数解析到block类型中 3、通过crypto/x509中相应的Parse方法得到密钥(即crypto/rsa包中的PrivateKey和PublicKey)

根据这个流程,我们可以很容易的反过来生成密钥,保存到文件中。

二、生成密钥并编码保存到文件中

首先,我们需要生成密钥,在crypto/rsa包中有一个函数:

func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error)

该函数中,random可以直接传crypto/rand中的rand.Reader,而bits是密钥长度。

这样得到了一个PrivateKey类型的指针。我们看一下PrivateKey的定义:


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
}

可见,该类型中嵌入了PublicKey这个类型。而PublicKey类型的定义如下:


type PublicKey struct {
    N *big.Int // modulus
    E int      // public exponent
}

这些是RSA算法规定的。

接下来就是找到x509和pem中对应的方法处理。关键代码如下:


func GenRsaKey(bits int) error {
	// 生成私钥文件
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return err
	}
	derStream := x509.MarshalPKCS1PrivateKey(privateKey)
	block := &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: derStream,
	}
	file, err := os.Create("private.pem")
	if err != nil {
		return err
	}
	err = pem.Encode(file, block)
	if err != nil {
		return err
	}
	// 生成公钥文件
	publicKey := &privateKey.PublicKey
	derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
	if err != nil {
		return err
	}
	block = &pem.Block{
		Type:  "PUBLIC KEY",
		Bytes: derPkix,
	}
	file, err = os.Create("public.pem")
	if err != nil {
		return err
	}
	err = pem.Encode(file, block)
	if err != nil {
		return err
	}
	return nil
}

以上代码将公钥和私钥分别写入public.pem和private.pem中了。 生成这两个文件后,可以用上篇文章中的方法验证一下正确性。

完整示例代码在github上。myblog_article_code rsa/rsa_gen_key.go这个文件

注:rsa中还有另外一个方法生成密钥

func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (priv *PrivateKey, err error)

有兴趣的可以研究一下。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门