• golang中的RSA算法,加密解密,签名校验,导出公钥密钥,导入公钥密钥


    RSA算法广泛应用与数据加密(比如 SSL 传输层加密),数字签名(比如支付宝的支付签名)。

    1、加密解密

    // encrypts the given message with RSA-OAEP
    func f1() {
    	// random 用来生成随机的素数
    	rsaPriviteKey, err := rsa.GenerateKey(rand.Reader, 1024)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	str := "raoxiaoya"
    
    	encdata, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, &rsaPriviteKey.PublicKey, []byte(str), nil)
    	if err != nil {
    		log.Fatal(err)
    	}
    	log.Println(hex.EncodeToString(encdata))
    
    	decdata, err := rsa.DecryptOAEP(sha256.New(), nil, rsaPriviteKey, encdata, nil)
    	if err != nil {
    		log.Fatal(err)
    	}
    	log.Println(string(decdata))
    
    	// 通用的 Decode 方法
    	decdata2, err2 := rsaPriviteKey.Decrypt(rand.Reader, encdata, &rsa.OAEPOptions{Hash: crypto.SHA256, Label: nil})
    	if err2 != nil {
    		log.Fatal(err2)
    	}
    	log.Println(string(decdata2))
    }
    
    // encrypts the given message with RSA and the padding scheme from PKCS #1 v1.5
    func f2() {
    	rsaPriviteKey, err := rsa.GenerateKey(rand.Reader, 1024)
    	if err != nil {
    		log.Fatal(err)
    	}
    	str := "raoxiaoya"
    
    	encdata, err := rsa.EncryptPKCS1v15(rand.Reader, &rsaPriviteKey.PublicKey, []byte(str))
    	if err != nil {
    		log.Fatal(err)
    	}
    	log.Println(hex.EncodeToString(encdata))
    
    	decdata, err := rsa.DecryptPKCS1v15(nil, rsaPriviteKey, encdata)
    	if err != nil {
    		log.Fatal(err)
    	}
    	log.Println(string(decdata))
    
    	// 通用的 Decode 方法
    	decdata2, err2 := rsaPriviteKey.Decrypt(rand.Reader, encdata, nil)
    	if err2 != nil {
    		log.Fatal(err2)
    	}
    	log.Println(string(decdata2))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    2、数字签名

    func f3() {
    	rsaPriviteKey, err := rsa.GenerateKey(rand.Reader, 1024)
    	if err != nil {
    		log.Fatal(err)
    	}
    	str := []byte("raoxiaoya")
    
    	// 由于 rsa 算法比较慢,所以先使用哈希算法来缩短加密的数据
    	hashed := sha256.Sum256(str)
    
    	// random 参数是预留问题,可以设置为nil
    	// 使用私钥来签名
    	signature, err := rsa.SignPKCS1v15(nil, rsaPriviteKey, crypto.SHA256, hashed[:])
    	if err != nil {
    		log.Fatal(err)
    	}
    	log.Println(hex.EncodeToString(signature))
    
    	// 使用公钥来验证签名
    	err = rsa.VerifyPKCS1v15(&rsaPriviteKey.PublicKey, crypto.SHA256, hashed[:], signature)
    	log.Fatal(err)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3、将RSA密钥导出到PEM文件

    func f4() {
    	rsaPriviteKey, err := rsa.GenerateKey(rand.Reader, 1024)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	pri := x509.MarshalPKCS1PrivateKey(rsaPriviteKey)
    	block := &pem.Block{
    		Type:  "RSA PRIVATE KEY",
    		Bytes: pri,
    	}
    	file, err := os.Create("private.pem")
    	if err != nil {
    		log.Fatal(err)
    	}
    	err = pem.Encode(file, block)
    	if err != nil {
    		log.Fatal(err)
    	}
    	pub := x509.MarshalPKCS1PublicKey(&rsaPriviteKey.PublicKey)
    	block2 := &pem.Block{
    		Type:  "PUBLIC KEY",
    		Bytes: pub,
    	}
    	file2, err2 := os.Create("public.pem")
    	if err2 != nil {
    		log.Fatal(err2)
    	}
    	err2 = pem.Encode(file2, block2)
    	if err2 != nil {
    		log.Fatal(err2)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    文件内容如下

    -----BEGIN RSA PRIVATE KEY-----
    MIICXgIBAAKBgQDFgklwSCKCIdoMoPbRrS/kYAlHfbq6SyjBx+6rvQ8muGEBtt+n
    SwQQEsPRGyIfe/bN/E0lh1iONqhO3z1qiQoOGc1mAlq3/So8dXOx3HWTGyhbvKZi
    O/suGsjAx/OIrmeaHuypMK5uY2TXx0CI2a4h3JyQ/X9WzfCZRs3uZhAb6wIDAQAB
    AoGBAKSTQMBnyyFmNbxKMABdcEe64mCI2pw63nZCM5U1DzfzcRmtmUVcE8GU8Uf/
    dPqJIAlaD6qS0e6Gis5V5GYuVIoejjruEZDVLB/VULg3hqFrwHmjCxZ8tevQxAXf
    nFMO0pycmLB4MIh2PlupSdN7QACAnFY/DQatiV7xjfHzll0hAkEA5ghQrDDEqLfn
    fau5rK5K3+Gi8W8z++GMizWUnlxJMKrJycTcoYnDUFCb/W2Q39WTvEFNBSfSIzg3
    iFqGXiEU0QJBANvOE7ySosZTGLoHptdueH3MMqN351QZ8okyCWwf9kQS1sI8dBl9
    4BrTAccR7YfxQuzk0CK5QJPcqLRhvEPOQ/sCQQDYcgaGnzTMlI7LnyQMqctmMcfC
    aaJ+ZVJ7QqVfBPMRSgKpSgVYMmqHTfIZWlkxZKOoRcGVEk0WOrV2Jce9Fl+hAkEA
    ryob+mQVCd2A0Ad3AymLJh0Loc/U7uW6rXDNp3gVJgypTqMklogEhvvu57i2xWYT
    wntaDsH435yyaQWWJacD7wJAQ8ShSWEWThuS+OgRh9j/UpFzXi5MKolQdnWefYCd
    2QZRir4eF27Y0TaRr4YvDSddmHW+yGa0Uy2xcWooSSUQSQ==
    -----END RSA PRIVATE KEY-----
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    -----BEGIN PUBLIC KEY-----
    MIGJAoGBAMWCSXBIIoIh2gyg9tGtL+RgCUd9urpLKMHH7qu9Dya4YQG236dLBBAS
    w9EbIh979s38TSWHWI42qE7fPWqJCg4ZzWYCWrf9Kjx1c7HcdZMbKFu8pmI7+y4a
    yMDH84iuZ5oe7Kkwrm5jZNfHQIjZriHcnJD9f1bN8JlGze5mEBvrAgMBAAE=
    -----END PUBLIC KEY-----
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4、加载现有的RSA密钥文件进行加密解密

    func f5() {
    	// load public.pem
    	pf, err := os.Open("public.pem")
    	if err != nil {
    		log.Fatal(err)
    	}
    	pfc, err := io.ReadAll(pf)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	block, _ := pem.Decode(pfc)
    	if block == nil {
    		log.Fatal("pem decode fail.")
    	}
    
    	rsaPublicKey, err := x509.ParsePKCS1PublicKey(block.Bytes)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// load private.pem
    	pvf, err := os.Open("private.pem")
    	if err != nil {
    		log.Fatal(err)
    	}
    	pvfc, err := io.ReadAll(pvf)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	blockv, _ := pem.Decode(pvfc)
    	if block == nil {
    		log.Fatal("pem decode fail.")
    	}
    
    	rsaPrivateKey, err := x509.ParsePKCS1PrivateKey(blockv.Bytes)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// test
    	str := "raoxiaoya"
    	encdata, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPublicKey, []byte(str))
    	if err != nil {
    		log.Fatal(err)
    	}
    	log.Println(hex.EncodeToString(encdata))
    
    	decdata, err := rsa.DecryptPKCS1v15(nil, rsaPrivateKey, encdata)
    	if err != nil {
    		log.Fatal(err)
    	}
    	log.Println(string(decdata))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    5、使用openssl程序生成RSA公钥密钥

    openssl genrsa -out rsa_private_key.pem 1024
    
    openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
    
    • 1
    • 2
    • 3
  • 相关阅读:
    SpringMvc的核心组件和执行流程
    ECCV 2022|文本图像分析领域再起波澜,波士顿大学联合MIT和谷歌提出全新多模态新闻数据集NewsStories
    并发编程之深入理解CAS
    CPU vs GPU:谁更适合进行图像处理?
    电脑扫描不到端口了怎么回事啊?
    汇编常用寄存器以及寻址方式
    重装系统后打印机状态已暂停如何恢复
    wangEditor5在vue中的基本使用
    编写支持灵活过滤的列表接口以解析前端过滤表达式
    大数据与AI:解析智慧城市的幕后英雄
  • 原文地址:https://blog.csdn.net/raoxiaoya/article/details/133815935