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

综合编程 2013-01-18


《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)

有兴趣的可以研究一下。

您可能感兴趣的

非对称加密与椭圆曲线 加密一直是通信领域的重要话题,我们经常听说各类算法,什么对称加密,非对称加密等等这类名词,云山雾绕,不得所以,经过这段时间的了解,接下来让我用九浅一深的语言,解释这个听上去深不可测,其实更是一头雾水的概念。 要解释加密技术,首先就要了解一下什么是对称加密。 对称加密 维基百科的解释...
Accelerate SHA256 Computations in Pure Go Using AV... sha256-simd Accelerate SHA256 computations in pure Go using AVX512 and AVX2 for Intel and ARM64 for ARM. On AVX512 it provides an up to 8x improveme...
韩国网络托管公司Nayana向勒索软件黑客支付100万美元... 据外媒6月12日报道,韩国网络托管公司 Nayana 上周末(6月10日)遭受网络攻击,导致旗下153台Linux 服务器与3,400个网站感染Erebus勒索软件。近日,该公司在努力无果的情况下,向勒索黑客支付价值100万美元的比特币,来解密锁定的文件。 在此次勒索事件中,勒索软件Ere...
Encrypting Inside WSO2 ESB Using the AES Algorithm In integration development, you will come across instances where you need to hold a payload in an intermediate place before it reaches its final desti...
HiNet 與 DigitalOcean、Linode、Vultr 的封包情況... 先說結論,綜合網路與 CPU 的情況,我剛好跟下面提到的文章給出相反的選擇 (i.e. 完全不會選 DigitalOcean )。如果是需要 latency 低的品質我會選 Linode 的東京新機房 Tokyo 2,如果不需要 latency 的我會選 Vultr 的 USD$2.5/mo...