[Golang軟件推薦] RSA公私鑰加解密(解決Golang私鑰加密公鑰解密問題)

安全是軟件開始中很重要的一個環節,在金融場景以及設計資產的場景下更是如此,在加密算法中主要使用較多加密方式分別是對稱加密和非對稱加密,對稱加密中的表明是AES,DES,3DES等,非對稱加密中使用比較多的是RSA,ECC等,最近火熱的比特幣中就使用ECC橢圓曲線算法,本篇文章主要是筆者在使用Golang在使用RSA中使用私鑰加密公鑰解密中遇到的問題,以及尋找的解決方案進行闡述,但願能夠幫助到你們!html

附上:git

喵了個咪的博客:w-blog.cngithub

gorsa-Github地址:https://github.com/farmerx/gorsa算法

喵咪優化過的gorsa-Github地址:https://github.com/wenzhenxi/gorsa安全

PS:特別感謝farmerx提供的gorsa實現服務器

1.瞭解RSA

要了解RSA就要先分別對稱加密和非對稱加密的區別:併發

  • 對稱加密中只有一個鑰匙也就是KEY,加解密都依靠這組密鑰
  • 非對稱加密中有公私鑰之分,私鑰能夠生產公鑰(比特幣的錢包地址就是公鑰),通常加密經過公鑰加密私鑰解密(也有私鑰加密公鑰解密)

RSA使用場景:app

  1. 咱們最熟悉的就是HTTPS中就是使用的RSA加密,CA機構給你頒發的就是私鑰給到咱們進行配置,在請求過程當中端用CA內置到系統的公鑰加密,請求道服務器由服務器進行解密驗證,保障了傳輸過程當中的請求加密ide

  2. 高安全場景(好比金融設備銀聯交易等)下的雙向認證(一機一密鑰),每臺機器本地都會生成一組公私鑰對,而且吧公鑰發送給服務器,這個使用發起的請求模型以下:優化


服務器的公私鑰對簡稱: s_puk,s_pvk

端生成的公私鑰對簡稱: c_puk,c_pvk

服務器存儲: s_pvk和c_puk

端存儲 :s_puk,c_pvk

端使用c_pvk加密請求 -> 服務器使用c_puk解密(驗證端) -> 使用s_pvk加密返回結果返回 -> 端使用s_puk解密得到返回結果(驗證服務器)

這個過程當中就完成了端認證服務器,服務器認證端稱之爲雙向認證(這裏是指簡單的表達這個模型,更加安全的模式中會引入加密機進一步保障安全)


PS:關於RSA加密的具體算法實現能夠參考如下兩篇文章

RSA算法原理(一)

RSA算法原理(二)

2.GoRSA

在Golang使用RSA加密算法的時候筆者遇到了一個坑,在網上找遍了官方提供的庫crypto/rsa中只有公鑰加密私鑰解密的實現,意味着沒法實現私鑰加密公鑰解密,而要實現雙向認證必需要使用私鑰加密公鑰解密,經過幾個小時的尋找其實有不少論壇中也在討論這個問題,也有童鞋在GITHUB上面說起了一些解決方案,有用C封裝了一次的等,可是使用其餘特別難受甚至運行不起來,在快要絕望的時候找到了貌似可使用的庫,經過查看源碼使用的是軟實現,在這裏推薦給你們

基於 https://github.com/farmerx/gorsa 進行封裝優化了以下幾點:

  • 優化公私鑰須要提早註冊初始化,在併發狀況下公私鑰匙會混亂的問題
  • 加密機沒有進行base64處理,在跨程序傳遞或存儲過程當中都須要base64避免二次封裝
  • 傳入返回都統一使用string類型避免轉換麻煩

獲取擴展包:

go get github.com/wenzhenxi/gorsa

具體使用:

package main

import (
	"log"
	"errors"
	"github.com/wenzhenxi/gorsa"
)

var Pubkey = `-----BEGIN 公鑰-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk+89V7vpOj1rG6bTAKYM
56qmFLwNCBVDJ3MltVVtxVUUByqc5b6u909MmmrLBqS//PWC6zc3wZzU1+ayh8xb
UAEZuA3EjlPHIaFIVIz04RaW10+1xnby/RQE23tDqsv9a2jv/axjE/27b62nzvCW
eItu1kNQ3MGdcuqKjke+LKhQ7nWPRCOd/ffVqSuRvG0YfUEkOz/6UpsPr6vrI331
hWRB4DlYy8qFUmDsyvvExe4NjZWblXCqkEXRRAhi2SQRCl3teGuIHtDUxCskRIDi
aMD+Qt2Yp+Vvbz6hUiqIWSIH1BoHJer/JOq2/O6X3cmuppU4AdVNgy8Bq236iXvr
MQIDAQAB
-----END 公鑰-----
`

var Pirvatekey = `-----BEGIN 私鑰-----
MIIEpAIBAAKCAQEAk+89V7vpOj1rG6bTAKYM56qmFLwNCBVDJ3MltVVtxVUUByqc
5b6u909MmmrLBqS//PWC6zc3wZzU1+ayh8xbUAEZuA3EjlPHIaFIVIz04RaW10+1
xnby/RQE23tDqsv9a2jv/axjE/27b62nzvCWeItu1kNQ3MGdcuqKjke+LKhQ7nWP
RCOd/ffVqSuRvG0YfUEkOz/6UpsPr6vrI331hWRB4DlYy8qFUmDsyvvExe4NjZWb
lXCqkEXRRAhi2SQRCl3teGuIHtDUxCskRIDiaMD+Qt2Yp+Vvbz6hUiqIWSIH1BoH
Jer/JOq2/O6X3cmuppU4AdVNgy8Bq236iXvrMQIDAQABAoIBAQCCbxZvHMfvCeg+
YUD5+W63dMcq0QPMdLLZPbWpxMEclH8sMm5UQ2SRueGY5UBNg0WkC/R64BzRIS6p
jkcrZQu95rp+heUgeM3C4SmdIwtmyzwEa8uiSY7Fhbkiq/Rly6aN5eB0kmJpZfa1
6S9kTszdTFNVp9TMUAo7IIE6IheT1x0WcX7aOWVqp9MDXBHV5T0Tvt8vFrPTldFg
IuK45t3tr83tDcx53uC8cL5Ui8leWQjPh4BgdhJ3/MGTDWg+LW2vlAb4x+aLcDJM
CH6Rcb1b8hs9iLTDkdVw9KirYQH5mbACXZyDEaqj1I2KamJIU2qDuTnKxNoc96HY
2XMuSndhAoGBAMPwJuPuZqioJfNyS99x++ZTcVVwGRAbEvTvh6jPSGA0k3cYKgWR
NnssMkHBzZa0p3/NmSwWc7LiL8whEFUDAp2ntvfPVJ19Xvm71gNUyCQ/hojqIAXy
tsNT1gBUTCMtFZmAkUsjqdM/hUnJMM9zH+w4lt5QM2y/YkCThoI65BVbAoGBAMFI
GsIbnJDNhVap7HfWcYmGOlWgEEEchG6Uq6Lbai9T8c7xMSFc6DQiNMmQUAlgDaMV
b6izPK4KGQaXMFt5h7hekZgkbxCKBd9xsLM72bWhM/nd/HkZdHQqrNAPFhY6/S8C
IjRnRfdhsjBIA8K73yiUCsQlHAauGfPzdHET8ktjAoGAQdxeZi1DapuirhMUN9Zr
kr8nkE1uz0AafiRpmC+cp2Hk05pWvapTAtIXTo0jWu38g3QLcYtWdqGa6WWPxNOP
NIkkcmXJjmqO2yjtRg9gevazdSAlhXpRPpTWkSPEt+o2oXNa40PomK54UhYDhyeu
akuXQsD4mCw4jXZJN0suUZMCgYAgzpBcKjulCH19fFI69RdIdJQqPIUFyEViT7Hi
bsPTTLham+3u78oqLzQukmRDcx5ddCIDzIicMfKVf8whertivAqSfHytnf/pMW8A
vUPy5G3iF5/nHj76CNRUbHsfQtv+wqnzoyPpHZgVQeQBhcoXJSm+qV3cdGjLU6OM
HgqeaQKBgQCnmL5SX7GSAeB0rSNugPp2GezAQj0H4OCc8kNrHK8RUvXIU9B2zKA2
z/QUKFb1gIGcKxYr+LqQ25/+TGvINjuf6P3fVkHL0U8jOG0IqpPJXO3Vl9B8ewWL
cFQVB/nQfmaMa4ChK0QEUe+Mqi++MwgYbRHx1lIOXEfUJO+PXrMekw==
-----END 私鑰-----
`


func main() {
	// 公鑰加密私鑰解密
	if err := applyPubEPriD(); err != nil {
		log.Println(err)
	}
	// 公鑰解密私鑰加密
	if err := applyPriEPubD(); err != nil {
		log.Println(err)
	}
}

// 公鑰加密私鑰解密
func applyPubEPriD() error {
	pubenctypt, err := gorsa.PublicEncrypt(`hello world`,Pubkey)
	if err != nil {
		return err
	}

	pridecrypt, err := gorsa.PriKeyDecrypt(pubenctypt,Pirvatekey)
	if err != nil {
		return err
	}
	if string(pridecrypt) != `hello world` {
		return errors.New(`解密失敗`)
	}
	return nil
}

// 公鑰解密私鑰加密
func applyPriEPubD() error {
	prienctypt, err := gorsa.PriKeyEncrypt(`hello world`,Pirvatekey)
	if err != nil {
		return err
	}

	pubdecrypt, err := gorsa.PublicDecrypt(prienctypt,Pubkey)
	if err != nil {
		return err
	}
	if string(pubdecrypt) != `hello world` {
		return errors.New(`解密失敗`)
	}
	return nil
}

3 總結

RSA在軟件開發中運用普遍,若是你們也遇到了Golang私鑰加密公鑰解密問題,歡迎你們使用gorsa擴展解決問題,歡迎你們收藏點贊!

注:筆者能力有限有說的不對的地方但願你們可以指出,也但願多多交流!

相關文章
相關標籤/搜索