<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          圖解 Golang 實(shí)現(xiàn) RSA 加密和簽名(有示例)

          共 4547字,需瀏覽 10分鐘

           ·

          2020-11-13 18:37

          點(diǎn)擊上方藍(lán)色“Go語(yǔ)言中文網(wǎng)”關(guān)注,每天一起學(xué) Go

          本文介紹 RSA 干了什么,以及我們?cè)鯓佑?Go 實(shí)現(xiàn)它。

          RSA(Rivest–Shamir–Adleman)加密是使用最廣的安全數(shù)據(jù)加密算法之一。

          它是一種非對(duì)稱加密算法,也叫”單向加密“。用這種方式,任何人都可以很容易地對(duì)數(shù)據(jù)進(jìn)行加密,而只有用正確的”秘鑰“才能解密。

          如果你想跳過(guò)解釋直接看源碼,點(diǎn)擊這里[1]。

          RSA 加密,一言以蔽之

          RSA 是通過(guò)生成一個(gè)公鑰和一個(gè)私鑰進(jìn)行加/解密的。公鑰和私鑰是一起生成的,組成一對(duì)秘鑰對(duì)。

          公鑰可以用來(lái)加密任意的數(shù)據(jù),但不能用來(lái)解密。

          私鑰可以用來(lái)解密由它對(duì)應(yīng)的公鑰加密的數(shù)據(jù)。

          這意味著我們可以把我們的公鑰給任何想給的人。之后他們可以把想發(fā)送給我們的信息進(jìn)行加密,唯一能訪問(wèn)這些信息的方式就是用我們的私鑰進(jìn)行解密。

          秘鑰的生成過(guò)程,以及信息的加密解密過(guò)程不在本文討論范圍內(nèi),但是如果你想研究詳細(xì)信息,這里有一個(gè)關(guān)于此主題的強(qiáng)大視頻[2]

          秘鑰的生成

          我們要做的第一件事就是生成公鑰私鑰對(duì)。這些秘鑰是隨機(jī)生成的,在后面所有的處理中都會(huì)用到。

          我們用標(biāo)準(zhǔn)庫(kù) crypto/rsa[3] 來(lái)生成秘鑰,用 crypto/rand[4] 庫(kù)來(lái)生成隨機(jī)數(shù)。

          //?The?GenerateKey?method?takes?in?a?reader?that?returns?random?bits,?and
          //?the?number?of?bits
          privateKey,?err?:=?rsa.GenerateKey(rand.Reader,?2048)
          if?err?!=?nil?{
          ?panic(err)
          }

          //?The?public?key?is?a?part?of?the?*rsa.PrivateKey?struct
          publicKey?:=?privateKey.PublicKey

          //?use?the?public?and?private?keys
          //?...

          publicKeyprivateKey 變量分別用于加密和解密。

          加密

          我們用 EncryptOEAP[5] 函數(shù)來(lái)加密一串隨機(jī)的信息。我們需要為這個(gè)函數(shù)提供一些輸入:

          1. 一個(gè)哈希函數(shù),用了它之后要能保證即使輸入做了微小的改變,輸出哈希也會(huì)變化很大。SHA256 適合于此。
          2. 一個(gè)用來(lái)生成隨機(jī)位的 random reader,這樣相同的內(nèi)容重復(fù)輸入時(shí)就不會(huì)有相同的輸出
          3. 之前生成的公鑰
          4. 我們想加密的信息
          5. 可選的標(biāo)簽參數(shù)(本文中我們忽略)
          encryptedBytes,?err?:=?rsa.EncryptOAEP(
          ?sha256.New(),
          ?rand.Reader,
          ?&publicKey,
          ?[]byte("super?secret?message"),
          ?nil)
          if?err?!=?nil?{
          ?panic(err)
          }

          fmt.Println("encrypted?bytes:?",?encryptedBytes)

          這段代碼會(huì)打印加密后的字節(jié),看起來(lái)有點(diǎn)像無(wú)用的信息。

          解密

          如果想訪問(wèn)加密字節(jié)承載的信息,就需要對(duì)它們進(jìn)行解密。

          解密它們的唯一方法就是使用與加密時(shí)的公鑰對(duì)應(yīng)的私鑰。

          *rsa.PrivateKey 結(jié)構(gòu)體有一個(gè)方法 Decrypt[6],我們使用這個(gè)方法從加密數(shù)據(jù)中解出原始的信息。

          解密時(shí)我們需要輸入的參數(shù)有:1. 被加密的數(shù)據(jù)(稱為密文)2. 加密數(shù)據(jù)用的哈希

          //?The?first?argument?is?an?optional?random?data?generator?(the?rand.Reader?we?used?before)
          //?we?can?set?this?value?as?nil
          //?The?OEAPOptions?in?the?end?signify?that?we?encrypted?the?data?using?OEAP,?and?that?we?used
          //?SHA256?to?hash?the?input.
          decryptedBytes,?err?:=?privateKey.Decrypt(nil,?encryptedBytes,?&rsa.OAEPOptions{Hash:?crypto.SHA256})
          if?err?!=?nil?{
          ?panic(err)
          }

          //?We?get?back?the?original?information?in?the?form?of?bytes,?which?we
          //?the?cast?to?a?string?and?print
          fmt.Println("decrypted?message:?",?string(decryptedBytes))

          簽名和校驗(yàn)

          RSA 秘鑰也用于簽名和校驗(yàn)。簽名不同于加密,簽名可以讓你宣示真實(shí)性,而不是機(jī)密性。

          也就是說(shuō),由原始信息生成一段數(shù)據(jù),稱為“簽名”,而不是偽裝原始信息的內(nèi)容(像加密[7]中做的那樣)。

          有簽名、信息和公鑰的任何人,可以用 RSA 校驗(yàn)來(lái)確保信息就是來(lái)自擁有公鑰的人。如果數(shù)據(jù)和簽名不匹配,校驗(yàn)不通過(guò)。

          請(qǐng)注意,只有擁有私鑰的人才能對(duì)信息進(jìn)行簽名,但是有公鑰的人可以驗(yàn)證它。

          msg?:=?[]byte("verifiable?message")

          //?Before?signing,?we?need?to?hash?our?message
          //?The?hash?is?what?we?actually?sign
          msgHash?:=?sha256.New()
          _,?err?=?msgHash.Write(msg)
          if?err?!=?nil?{
          ?panic(err)
          }
          msgHashSum?:=?msgHash.Sum(nil)

          //?In?order?to?generate?the?signature,?we?provide?a?random?number?generator,
          //?our?private?key,?the?hashing?algorithm?that?we?used,?and?the?hash?sum
          //?of?our?message
          signature,?err?:=?rsa.SignPSS(rand.Reader,?privateKey,?crypto.SHA256,?msgHashSum,?nil)
          if?err?!=?nil?{
          ?panic(err)
          }

          //?To?verify?the?signature,?we?provide?the?public?key,?the?hashing?algorithm
          //?the?hash?sum?of?our?message?and?the?signature?we?generated?previously
          //?there?is?an?optional?"options"?parameter?which?can?omit?for?now
          err?=?rsa.VerifyPSS(&publicKey,?crypto.SHA256,?msgHashSum,?signature,?nil)
          if?err?!=?nil?{
          ?fmt.Println("could?not?verify?signature:?",?err)
          ?return
          }
          //?If?we?don't?get?any?error?from?the?`VerifyPSS`?method,?that?means?our
          //?signature?is?valid
          fmt.Println("signature?verified")

          總結(jié)

          本文中我們看到了如何生成 RSA 公鑰和私鑰,以及怎樣使用它們進(jìn)行加密、解密、簽名和驗(yàn)證任意數(shù)據(jù)。

          在將它們用于你的數(shù)據(jù)之前,你需要了解一些使用限制。首先,你要加密的數(shù)據(jù)必須比你的秘鑰短。例如,EncryptOAEP 文檔[8] 中說(shuō)“(要加密的)信息不能比公布的模數(shù)減去哈希長(zhǎng)度的兩倍后再減去 2 長(zhǎng)”。

          使用的哈希算法要適合你的需求。SHA256(在本例中用的就是 SHA256)可以用于大部分案例,但是如果是對(duì)數(shù)據(jù)要求更高的應(yīng)用,你可能需要用 SHA512。

          你可以在這里[9]找到所有示例的源碼。


          via: https://www.sohamkamani.com/golang/rsa-encryption/

          作者:Soham Kamani[10]譯者:lxbwolf[11]校對(duì):polaris1119[12]

          本文由 GCTT[13] 原創(chuàng)編譯,Go 中文網(wǎng)[14] 榮譽(yù)推出

          參考資料

          [1]

          這里: https://gist.github.com/sohamkamani/08377222d5e3e6bc130827f83b0c073e

          [2]

          強(qiáng)大視頻: https://www.youtube.com/watch?v=wXB-V_Keiu8

          [3]

          crypto/rsa: https://pkg.go.dev/crypto/rsa?tab=doc

          [4]

          crypto/rand: https://pkg.go.dev/crypto/rand?tab=doc

          [5]

          EncryptOEAP: https://pkg.go.dev/crypto/rsa?tab=doc#EncryptOAEP

          [6]

          Decrypt: https://pkg.go.dev/crypto/rsa?tab=doc#PrivateKey.Decrypt

          [7]

          加密: https://www.sohamkamani.com/golang/rsa-encryption/#encryption

          [8]

          EncryptOAEP 文檔: https://pkg.go.dev/crypto/rsa?tab=doc#EncryptOAEP

          [9]

          這里: https://gist.github.com/sohamkamani/08377222d5e3e6bc130827f83b0c073e

          [10]

          Soham Kamani: https://twitter.com/sohamkamani

          [11]

          lxbwolf: https://github.com/lxbwolf

          [12]

          polaris1119: https://github.com/polaris1119

          [13]

          GCTT: https://github.com/studygolang/GCTT

          [14]

          Go 中文網(wǎng): https://studygolang.com/



          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù) ebook 獲??;還可以回復(fù)「進(jìn)群」,和數(shù)萬(wàn) Gopher 交流學(xué)習(xí)。

          瀏覽 80
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产XXXX少 | 超碰97自拍 | 欧美操逼视屏 | 日韩另类 | 色婷婷精品国产一区二区三区 |