安全是軟件開始中很重要的一個環節,在金融場景以及設計資產的場景下更是如此,在加密算法中主要使用較多加密方式分別是對稱加密和非對稱加密,對稱加密中的表明是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實現服務器
要了解RSA就要先分別對稱加密和非對稱加密的區別:併發
RSA使用場景:app
咱們最熟悉的就是HTTPS中就是使用的RSA加密,CA機構給你頒發的就是私鑰給到咱們進行配置,在請求過程當中端用CA內置到系統的公鑰加密,請求道服務器由服務器進行解密驗證,保障了傳輸過程當中的請求加密ide
高安全場景(好比金融設備銀聯交易等)下的雙向認證(一機一密鑰),每臺機器本地都會生成一組公私鑰對,而且吧公鑰發送給服務器,這個使用發起的請求模型以下:優化
服務器的公私鑰對簡稱: 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加密的具體算法實現能夠參考如下兩篇文章
在Golang使用RSA加密算法的時候筆者遇到了一個坑,在網上找遍了官方提供的庫crypto/rsa中只有公鑰加密私鑰解密的實現,意味着沒法實現私鑰加密公鑰解密,而要實現雙向認證必需要使用私鑰加密公鑰解密,經過幾個小時的尋找其實有不少論壇中也在討論這個問題,也有童鞋在GITHUB上面說起了一些解決方案,有用C封裝了一次的等,可是使用其餘特別難受甚至運行不起來,在快要絕望的時候找到了貌似可使用的庫,經過查看源碼使用的是軟實現,在這裏推薦給你們
基於 https://github.com/farmerx/gorsa 進行封裝優化了以下幾點:
獲取擴展包:
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 }
RSA在軟件開發中運用普遍,若是你們也遇到了Golang私鑰加密公鑰解密問題,歡迎你們使用gorsa擴展解決問題,歡迎你們收藏點贊!
注:筆者能力有限有說的不對的地方但願你們可以指出,也但願多多交流!