golang rsa pkcs8

发布时间:2024-12-23 00:12:29

开头

在golang开发中,RSA加密算法是一项非常重要的功能,它可以用来对数据进行安全传输和存储。而在使用RSA算法进行加密和解密时,我们通常会涉及到PKCS #8标准。PKCS #8定义了一种通用的私钥信息语法,可以让不同的加密算法使用相同的私钥表示方式,并且支持多种编码格式。本文将介绍如何在golang中使用RSA PKCS #8。

生成RSA密钥对

首先,我们需要生成一个RSA密钥对,其中包括一个私钥和一个公钥。在golang中,可以使用crypto/rsa包来生成RSA密钥对。我们可以调用GenerateKey函数来生成一个指定位数的密钥对。下面是一个示例代码:

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"os"
)

func generateRSAKeyPair(bits int) (*rsa.PrivateKey, error) {
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return nil, fmt.Errorf("failed to generate private key: %w", err)
	}

	return privateKey, nil
}

func main() {
	privateKey, err := generateRSAKeyPair(2048)
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to generate RSA key pair: %v\n", err)
		os.Exit(1)
	}

	// Save private key to file
	privateKeyFile, err := os.Create("private.key")
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to create private key file: %v\n", err)
		os.Exit(1)
	}
	defer privateKeyFile.Close()

	privateKeyPEM := &pem.Block{
		Type:  "PRIVATE KEY",
		Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
	}

	if err := pem.Encode(privateKeyFile, privateKeyPEM); err != nil {
		fmt.Fprintf(os.Stderr, "failed to write private key to file: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("RSA private key is saved to private.key file")
}

以上代码首先使用GenerateKey函数生成一个2048位的RSA私钥,然后使用x509.MarshalPKCS1PrivateKey函数将私钥序列化为DER编码的字节数组。接下来,通过pem.Block结构体和pem.Encode函数将DER编码的私钥转换为PEM格式,并将其保存到private.key文件中。

加载RSA私钥

在使用RSA PKCS #8进行加密和解密操作之前,我们需要先加载RSA私钥。在golang中,可以使用crypto/x509包来解析PEM格式的私钥,并生成相应的rsa.PrivateKey结构体。

package main

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"os"
)

func loadRSAPrivateKeyFromFile(filename string) (*rsa.PrivateKey, error) {
	privateKeyPEM, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, fmt.Errorf("failed to read private key file: %w", err)
	}

	block, _ := pem.Decode(privateKeyPEM)
	if block == nil {
		return nil, fmt.Errorf("failed to decode private key PEM")
	}

	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, fmt.Errorf("failed to parse private key: %w", err)
	}

	return privateKey, nil
}

func main() {
	privateKey, err := loadRSAPrivateKeyFromFile("private.key")
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to load RSA private key: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("Loaded RSA private key: %v\n", privateKey)
}

以上代码通过ioutil.ReadFile函数读取private.key文件中的PEM格式私钥数据,然后使用pem.Decode函数解码PEM数据并返回一个pem.Block结构体。最后,通过x509.ParsePKCS1PrivateKey函数将DER编码的私钥数据转换为rsa.PrivateKey结构体。

RSA加密和解密

有了RSA私钥之后,我们就可以使用它进行加密和解密操作了。在golang中,可以使用crypto/rsa包提供的Encrypt和Decrypt方法来实现RSA加密和解密。

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"encoding/base64"
	"fmt"
	"os"
)

func rsaEncrypt(publicKey *rsa.PublicKey, data []byte) ([]byte, error) {
	ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, data)
	if err != nil {
		return nil, fmt.Errorf("failed to encrypt data: %w", err)
	}

	return ciphertext, nil
}

func rsaDecrypt(privateKey *rsa.PrivateKey, ciphertext []byte) ([]byte, error) {
	plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, ciphertext)
	if err != nil {
		return nil, fmt.Errorf("failed to decrypt data: %w", err)
	}

	return plaintext, nil
}

func main() {
	// Load RSA private key
	privateKey, err := loadRSAPrivateKeyFromFile("private.key")
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to load RSA private key: %v\n", err)
		os.Exit(1)
	}

	// Encrypt data using RSA public key
	publicKey := &privateKey.PublicKey
	data := []byte("Hello, RSA!")

	ciphertext, err := rsaEncrypt(publicKey, data)
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to encrypt data: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("Encrypted data: %s\n", base64.StdEncoding.EncodeToString(ciphertext))

	// Decrypt data using RSA private key
	plaintext, err := rsaDecrypt(privateKey, ciphertext)
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to decrypt data: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("Decrypted data: %s\n", plaintext)
}

以上代码首先加载RSA私钥(使用前面介绍的loadRSAPrivateKeyFromFile函数)。然后,定义了一个测试数据data,通过rsaEncrypt函数使用RSA公钥对数据进行加密,得到密文ciphertext。再通过rsaDecrypt函数使用RSA私钥对密文进行解密,得到明文plaintext。

相关推荐