侧边栏壁纸
博主头像
SeaDream乄造梦

Dream,Don't stop a day of hard and don't give up a little hope。 ——不停止一日努力&&不放弃一点希望。

  • 累计撰写 86 篇文章
  • 累计创建 21 个标签
  • 累计收到 14 条评论

目 录CONTENT

文章目录

rsa 非对称加密解密

SeaDream乄造梦
2025-03-14 / 0 评论 / 0 点赞 / 117 阅读 / 9,538 字
温馨提示:
亲爱的,如果觉得博主很有趣就留下你的足迹,并收藏下链接在走叭

为什么要使用加密传输呢?

避免网络传输过程中敏感信息泄露,避免泄露平台用户信息。

go和java加密解密写法

go

package test

import (
	randRsa "crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/json"
	"encoding/pem"
	"fmt"
	"sync"
	"testing"
)

// 生成 RSA 密钥对
func generateRSAKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
	privateKey, err := rsa.GenerateKey(randRsa.Reader, bits)
	if err != nil {
		return nil, nil, err
	}
	return privateKey, &privateKey.PublicKey, nil
}

// 使用公钥加密
func encryptWithPublicKey(plainText string, publicKey *rsa.PublicKey) (string, error) {
	cipherText, err := rsa.EncryptPKCS1v15(randRsa.Reader, publicKey, []byte(plainText))
	if err != nil {
		return "", err
	}
	// 返回 Base64 编码后的加密文本
	return base64.StdEncoding.EncodeToString(cipherText), nil
}

// 使用私钥解密
func decryptWithPrivateKey(cipherText string, privateKey *rsa.PrivateKey) (string, error) {
	// 先解码 Base64
	decodedCipherText, err := base64.StdEncoding.DecodeString(cipherText)
	if err != nil {
		return "", err
	}

	// 使用私钥解密
	plainText, err := rsa.DecryptPKCS1v15(randRsa.Reader, privateKey, decodedCipherText)
	if err != nil {
		return "", err
	}

	return string(plainText), nil
}

func exportPrivateKeyToPEM(privateKey *rsa.PrivateKey) string {
	privKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)
	privKeyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: privKeyBytes})
	return string(privKeyPEM)
}

func exportPublicKeyToPEM(publicKey *rsa.PublicKey) string {
	pubKeyBytes, _ := x509.MarshalPKIXPublicKey(publicKey)
	pubKeyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pubKeyBytes})
	return string(pubKeyPEM)
}

func loadPrivateKeyFromPEM(pemStr string) (*rsa.PrivateKey, error) {
	block, _ := pem.Decode([]byte(pemStr))
	return x509.ParsePKCS1PrivateKey(block.Bytes)
}

func loadPublicKeyFromPEM(pemStr string) (*rsa.PublicKey, error) {
	block, _ := pem.Decode([]byte(pemStr))
	key, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	return key.(*rsa.PublicKey), nil
}

func TestRSA(t *testing.T) {
	// 生成 2048 位 RSA 密钥对
	privateKey, publicKey, err := generateRSAKeyPair(2048)
	if err != nil {
		fmt.Println("Error generating RSA key pair:", err)
		return
	}

	// 输出公钥私钥
	fmt.Println("Private Key:", exportPrivateKeyToPEM(privateKey))
	fmt.Println("Public Key:", exportPublicKeyToPEM(publicKey))

	originalText := "Hello, RSA encryption and decryption in Go!"
	fmt.Println("Original Text:", originalText)

	// 加密
	encryptedText, err := encryptWithPublicKey(originalText, publicKey)
	if err != nil {
		fmt.Println("Error encrypting:", err)
		return
	}
	fmt.Println("Encrypted Text (Base64):", encryptedText)

	// 解密
	decryptedText, err := decryptWithPrivateKey(encryptedText, privateKey)
	if err != nil {
		fmt.Println("Error decrypting:", err)
		return
	}
	fmt.Println("Decrypted Text:", decryptedText)
}

/**
 * 测试并发加密解密性能
 *
 * 运行结果:
 * goos: windows
 * goarch: amd64
 * pkg: wann-redmoon/test
 * cpu: 12th Gen Intel(R) Core(TM) i5-12400F
 * BenchmarkRSACrypto
 * BenchmarkRSACrypto/ConcurrentEncryptionDecryption
 * BenchmarkRSACrypto/ConcurrentEncryptionDecryption-12         	1000000000	         0.04600 ns/op
PASS
*/

func BenchmarkRSACrypto(b *testing.B) {
	// 生成 2048 位 RSA 密钥对
	privateKey, publicKey, err := generateRSAKeyPair(2048)
	if err != nil {
		b.Fatalf("Error generating RSA key pair: %v", err)
	}

	originalText := "Hello, RSA encryption and decryption in Go!"

	// 测量并发加密解密性能
	b.Run("ConcurrentEncryptionDecryption", func(b *testing.B) {
		var wg sync.WaitGroup

		// 运行多个并发任务来测试加密解密的性能
		for i := 0; i < 100; i++ {
			wg.Add(1)
			go func() {
				defer wg.Done()

				// 加密
				encryptedText, err := encryptWithPublicKey(originalText, publicKey)
				if err != nil {
					b.Errorf("Error encrypting: %v", err)
					return
				}

				// 解密
				_, err = decryptWithPrivateKey(encryptedText, privateKey)
				if err != nil {
					b.Errorf("Error decrypting: %v", err)
					return
				}
			}()
		}

		// 等待所有并发任务完成
		wg.Wait()
	})
}

/**
性能测试 整体加密解密,只加密解密部分字段
*/

type MyStruct struct {
	Name       string
	Age        int
	Password   string
	Email      string
	Address    string
	Phone      string
	Occupation string
	Country    string
	ZipCode    string
	Salary     float64
	JoinedAt   string
}

// 结构体转 JSON 后加密
func encryptStructToJSON(s MyStruct, publicKey *rsa.PublicKey) (string, error) {
	jsonData, err := json.Marshal(s)
	if err != nil {
		return "", err
	}
	return encryptWithPublicKey(string(jsonData), publicKey)
}

// 分别加密结构体的字段
func encryptFields(s MyStruct, publicKey *rsa.PublicKey) (MyStruct, error) {
	var encrypted MyStruct
	var err error
	encrypted.Name, err = encryptWithPublicKey(s.Name, publicKey)
	if err != nil {
		return encrypted, err
	}
	encrypted.Age = s.Age // 不加密
	encrypted.Password, err = encryptWithPublicKey(s.Password, publicKey)
	if err != nil {
		return encrypted, err
	}
	encrypted.Email, err = encryptWithPublicKey(s.Email, publicKey)
	if err != nil {
		return encrypted, err
	}
	encrypted.Address, err = encryptWithPublicKey(s.Address, publicKey)
	if err != nil {
		return encrypted, err
	}
	encrypted.Phone, err = encryptWithPublicKey(s.Phone, publicKey)
	if err != nil {
		return encrypted, err
	}
	encrypted.Occupation, err = encryptWithPublicKey(s.Occupation, publicKey)
	if err != nil {
		return encrypted, err
	}
	encrypted.Country, err = encryptWithPublicKey(s.Country, publicKey)
	if err != nil {
		return encrypted, err
	}
	encrypted.ZipCode, err = encryptWithPublicKey(s.ZipCode, publicKey)
	if err != nil {
		return encrypted, err
	}
	encrypted.Salary = s.Salary // 不加密
	encrypted.JoinedAt, err = encryptWithPublicKey(s.JoinedAt, publicKey)
	if err != nil {
		return encrypted, err
	}
	return encrypted, nil
}

// 基准测试:结构体转 JSON 后加密
func BenchmarkEncryptStructToJSON(b *testing.B) {
	_, publicKey, _ := generateRSAKeyPair(2048)
	originalStruct := MyStruct{
		Name: "Alice", Age: 30, Password: "password123", Email: "alice@example.com",
		Address: "123 Main St", Phone: "123-456-7890", Occupation: "Engineer", Country: "USA",
		ZipCode: "12345", Salary: 75000.5, JoinedAt: "2023-01-01",
	}

	b.ResetTimer()
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		_, _ = encryptStructToJSON(originalStruct, publicKey)
	}
}

/**
goos: windows
goarch: amd64
pkg: wann-redmoon/test
cpu: 12th Gen Intel(R) Core(TM) i5-12400F
BenchmarkEncryptStructToJSON
BenchmarkEncryptStructToJSON-12    	   24712	     47684 ns/op	   15586 B/op	     106 allocs/op
PASS

*/

// 基准测试:分别加密结构体字段
func BenchmarkEncryptFields(b *testing.B) {
	_, publicKey, _ := generateRSAKeyPair(2048)
	originalStruct := MyStruct{
		Name: "Alice", Age: 30, Password: "password123", Email: "alice@example.com",
		Address: "123 Main St", Phone: "123-456-7890", Occupation: "Engineer", Country: "USA",
		ZipCode: "12345", Salary: 75000.5, JoinedAt: "2023-01-01",
	}

	b.ResetTimer()
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		_, _ = encryptFields(originalStruct, publicKey)
	}
}

/**
goos: windows
goarch: amd64
pkg: wann-redmoon/test
cpu: 12th Gen Intel(R) Core(TM) i5-12400F
BenchmarkEncryptFields
BenchmarkEncryptFields-12    	    2866	    442560 ns/op	  134717 B/op	     931 allocs/op
PASS
*/


性能测试解释:

goos: windows:表示测试是在 Windows 操作系统上进行的。
goarch: amd64:表示测试是在 64 位架构的计算机上进行的。
pkg: wann-redmoon/test:表示基准测试运行在 wann-redmoon/test 包下。
cpu: 12th Gen Intel(R) Core(TM) i5-12400F:表示测试运行的 CPU 是第 12 代的 Intel Core i5-12400F 处理器。

基准测试输出:

BenchmarkRSACrypto/ConcurrentEncryptionDecryption:这个是你测试的基准测试用例的名称,表示测试的是并发加密和解密的性能。
BenchmarkRSACrypto/ConcurrentEncryptionDecryption-12:这个结果表示测试在 12 个并发的情况下运行。-12 是并发的数量,表示有 12 个 goroutine 在同时进行加密解密操作。
1000000000:表示基准测试的执行次数(每个 goroutine 执行的操作次数)。这个数值非常大(10 亿次),说明每个任务在短时间内就执行了大量的操作。
0.04278 ns/op:表示每个加密解密操作的平均耗时为 0.04278 纳秒。这个时间极其短,意味着你的加密解密操作非常快速。

BenchmarkEncryptStructToJSON 和 BenchmarkEncryptFields 的性能

  1. BenchmarkEncryptStructToJSON:
    BenchmarkEncryptStructToJSON-12 24712 47684 ns/op 15586 B/op 106 allocs/op
    运行时间:每次操作平均 47684 纳秒(约 47 毫秒)。
    内存分配:每次操作会分配约 15586 字节的内存。
    内存分配次数:每次操作进行 106 次内存分配。
  2. BenchmarkEncryptFields:
    BenchmarkEncryptFields-12 2866 442560 ns/op 134717 B/op 931 allocs/op
    运行时间:每次操作平均 442560 纳秒(约 442 毫秒)。
    内存分配:每次操作会分配约 134717 字节的内存。
    内存分配次数:每次操作进行 931 次内存分配。
分析:

运行时间:BenchmarkEncryptStructToJSON 显著比 BenchmarkEncryptFields 快,说明一次性对整个结构体进行 JSON 编码后加密,处理速度比逐个字段加密要快得多。

内存分配:BenchmarkEncryptFields 需要更多的内存分配(134717 字节),而 BenchmarkEncryptStructToJSON 的内存分配较少(15586 字节)。这是因为在 BenchmarkEncryptFields 中,每个字段都需要单独加密,因此会进行更多的内存分配。

内存分配次数:BenchmarkEncryptFields 的内存分配次数远高于 BenchmarkEncryptStructToJSON(931 次 vs. 106 次),这是由于每个字段都需要独立的加密处理并分配内存。

结论:

性能更好的方式:结构体转 JSON 后加密(BenchmarkEncryptStructToJSON)更快,且内存分配和处理更高效。
性能较差的方式:分别加密字段(BenchmarkEncryptFields)在处理时间、内存分配和分配次数上均显得更加低效。

java

package com.snpackage.web.controller;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.Base64;

public class TestRSAExample {
    // 生成RSA公钥私钥对
    public static KeyPair generateRSAKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 设置密钥的大小
        return keyPairGenerator.generateKeyPair();
    }

    // 使用公钥进行加密
    public static String encrypt(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes); // 返回加密后的字符串
    }

    // 使用私钥进行解密
    public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
        return new String(decryptedBytes); // 返回解密后的字符串
    }

    public static void main(String[] args) {
        try {
            // 生成RSA公钥私钥对
            KeyPair keyPair = generateRSAKeyPair();
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();

            // 原始数据
            String originalData = "Hello, RSA encryption and decryption!";
            System.out.println("Original Data: " + originalData);

            // 使用公钥加密
            String encryptedData = encrypt(originalData, publicKey);
            System.out.println("Encrypted Data: " + encryptedData);

            // 使用私钥解密
            String decryptedData = decrypt(encryptedData, privateKey);
            System.out.println("Decrypted Data: " + decryptedData);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

0

评论区