<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 加密和簽名(有示例)

          共 5850字,需瀏覽 12分鐘

           ·

          2021-04-18 22:03

          點(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ì)。

          這意味著我們可以把我們的公鑰給任何想給的人。之后他們可以把想發(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]中做的那樣)。

          請(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í)。

          瀏覽 132
          點(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>
                  鸡巴操逼网站 | 毛片毛片毛片多人 | 看免费的黄色大片 | 国产成人一区二区三区 | 成人免费看片 无需下载 |