<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與散列算法

          共 5895字,需瀏覽 12分鐘

           ·

          2021-12-17 17:17

          目錄

          • 1、哈希函數(shù)的基本特征

          • 2、SHA-1

          • 3、MD5

            • 3.1 基本使用-直接計算

            • 3.2 大量數(shù)據(jù)-散列計算

          • 4、SHA-1 與 MD5 的比較

          • 5、Hmac

          • 6、哈希函數(shù)的應(yīng)用


          散列是信息的提煉,通常其長度要比信息小得多,且為一個固定長度。加密性強的散列一定是不可逆的,這就意味著通過散列結(jié)果,無法推出任何部分的原始信息。任何輸入信息的變化,哪怕僅一位,都將導致散列結(jié)果的明顯變化,這稱之為雪崩效應(yīng)。散列還應(yīng)該是防沖突的,即找不出具有相同散列結(jié)果的兩條信息。具有這些特性的散列結(jié)果就可以用于驗證信息是否被修改。常用于保證數(shù)據(jù)完整性

          單向散列函數(shù)一般用于產(chǎn)生消息摘要,密鑰加密等,常見的有

          • MD5(Message Digest Algorithm 5):是RSA數(shù)據(jù)安全公司開發(fā)的一種單向散列算法
          • SHA(Secure Hash Algorithm):可以對任意長度的數(shù)據(jù)運算生成一個160位的數(shù)值

          1、哈希函數(shù)的基本特征

          哈希函數(shù)不是加密算法,其特征為單向性和唯一性

          具體如下

          • 輸入可以是任意長度
          • 輸出是固定長度
          • 根據(jù)輸入很容易計算出輸出
          • 根據(jù)輸出很難計算出輸入(幾乎不可能)
          • 兩個不同的輸入幾乎不可能得到相同的輸出

          2、SHA-1

          https://golang.google.cn/pkg/crypto/sha1/

          1993年,安全散列算法(SHA)由美國國家標準和技術(shù)協(xié)會(NIST)提出,并作為聯(lián)邦信息處理標準(FIPS PUB 180)公布;1995年又發(fā)布了一個修訂版FIPS PUB 180-1,通常稱之為SHA-1。SHA-1是基于MD4算法的,并且它的設(shè)計在很大程度上是模仿MD4的?,F(xiàn)在已成為公認的最安全的散列算法之一,并被廣泛使用

          SHA-1是一種數(shù)據(jù)加密算法,該算法的思想是接收一段明文,然后以一種不可逆的方式將它轉(zhuǎn)換成一段(通常更?。┟芪模部梢院唵蔚睦斫鉃槿∫淮斎氪a(稱為預映射或信息),并把它們轉(zhuǎn)化為長度較短、位數(shù)固定的輸出序列即散列值(也稱為信息摘要或信息認證代碼)的過程 該算法輸入報文的最大長度不超過264位,產(chǎn)生的輸出是一個160位的報文摘要。輸入是按512位的分組進行處理的。SHA-1是不可逆的、防沖突,并具有良好的雪崩效應(yīng)

          sha1SHA家族的五個算法之一(其它四個是SHA-224SHA-256、SHA-384,和SHA-512)

          SHA(Secure Hash Algorithm)安全散列算法,是一系列密碼散列函數(shù),有多個不同安全等級的版本:SHA-1,SHA-224,SHA-256,SHA-384,SHA-512

          防偽裝,防竄擾,保證信息的合法性和完整性

          算法流程:

          • 填充,使得數(shù)據(jù)長度對512求余的結(jié)果為448

          • 在信息摘要后面附加64bit,表示原始信息摘要的長度

          • 初始化h0h4,每個h都是32

          • h0h4歷經(jīng)80輪復雜的變換

          • h0h4拼接起來,構(gòu)成160位,返回

          常用函數(shù)

          • New:創(chuàng)建 Hash 對象用于計算字節(jié)/字符sha1
          • Sum:計算字節(jié)切片sha1
          package?main

          import?(
          ?"crypto/sha1"
          ?"fmt"
          )

          func?main()?{
          ?data?:=?[]byte("This?page?intentionally?left?blank.")
          ?fmt.Printf("%x\n",?sha1.Sum(data))
          }

          sha256、sha512同理

          使用示例

          package?main

          import?(
          ?"crypto/sha1"
          ?"fmt"
          ?"io"
          )
          //?sha1散列算法
          func?sha1Hash(msg?string)?(hashData?[]byte)?{
          ?h?:=?sha1.New()
          ?io.WriteString(h,?msg)
          ?hashData?=?h.Sum(nil)
          ?return
          }

          func?main()?{
          ?msg?:=?"This?is?the?message?to?hash!"
          ?//?sha1
          ?sha1Data?:=?sha1Hash(msg)
          ?fmt.Printf("SHA1:?%x\n",?sha1Data)
          }

          3、MD5

          https://golang.google.cn/pkg/crypto/md5/

          MD5Message-Digest Algorithm 5(信息-摘要算法 5),用于確保信息傳輸完整一致。是計算機廣泛使用的雜湊算法之一(又譯摘要算法、哈希算法),主流編程語言普遍已有MD5實現(xiàn)。將數(shù)據(jù)(如漢字)運算為另一固定長度值,是雜湊算法的基礎(chǔ)原理,MD5的前身有MD2、MD3MD4

          • 算法流程跟SHA-1大體相似

          • MD5的輸出是128位,比SHA-1短了32

          • MD5相對易受密碼分析的攻擊,運算速度比SHA-1

          常用函數(shù)

          • New:創(chuàng)建Hash對象用于計算字節(jié)/字符md5

          • Sum:計算字節(jié)切片md5

          import?(
          ?"crypto/md5"
          ?"fmt"
          )

          func?main()?{
          ????//?最基礎(chǔ)的使用方式:?Sum?返回數(shù)據(jù)的MD5校驗和
          ?fmt.Printf("%x\n",?md5.Sum([]byte("測試數(shù)據(jù)")))
          }

          3.1 基本使用-直接計算

          package?main

          import?(
          ?"crypto/md5"
          ?"encoding/hex"
          ?"fmt"
          )

          func?main()?{
          ?//?結(jié)果是byte類型的數(shù)組
          ?bytes?:=?md5.Sum([]byte("i?am?geek"))
          ?//?轉(zhuǎn)換為32位小寫
          ?fmt.Printf("%x\n",?bytes)??//?397f77c74db1e25084653531a8046f21
          ?//?轉(zhuǎn)換為字符串
          ?x?:=?fmt.Sprintf("%x\n",?bytes)
          ?fmt.Println(x)??//?397f77c74db1e25084653531a8046f21
          ?fmt.Println(hex.EncodeToString(bytes[:]))??//?397f77c74db1e25084653531a8046f21
          }

          3.2 大量數(shù)據(jù)-散列計算

          package?main

          import?(
          ?"crypto/md5"
          ?"fmt"
          )

          func?main()?{
          ?//?較大時,分開批量計算
          ?m?:=?md5.New()
          ?m.Write([]byte("i?am"))
          ?m.Write([]byte("?geek"))
          ?fmt.Printf("%x\n",?m.Sum(nil))??//?397f77c74db1e25084653531a8046f21
          }

          4、SHA-1 與 MD5 的比較

          因為二者均由MD4導出,SHA-1MD5彼此很相似。相應(yīng)的,他們的強度和其他特性也是相似,但還有以下幾點不同:

          • 對強行供給的安全性:最顯著和最重要的區(qū)別是SHA-1摘要比MD5摘要長32位。使用強行技術(shù),產(chǎn)生任何一個報文使其摘要等于給定報摘要的難度對MD52128數(shù)量級的操作,而對SHA-1則是2160數(shù)量級的操作。這樣,SHA-1對強行攻擊有更大的強度。
          • 對密碼分析的安全性:由于MD5的設(shè)計,易受密碼分析的攻擊,SHA-1顯得不易受這樣的攻擊。
          • 速度:在相同的硬件上,SHA-1的運行速度比MD5

          5、Hmac

          https://golang.google.cn/pkg/crypto/hmac/

          Hmac算法也是一種哈希算法,它可以利用MD5SHA1等哈希算法。不同的是,Hmac還需要一個密鑰, 只要密鑰發(fā)生了變化,那么同樣的輸入數(shù)據(jù)也會得到不同的簽名,因此,可以把Hmac理解為用隨機數(shù)“增強”的哈希算法

          常用函數(shù)

          • New:創(chuàng)建Hash對象用于計算字節(jié)/字符hmac
          • Equal:比較hmac值是否相等

          Hs256實現(xiàn)

          package?main

          import?(
          ?"crypto/hmac"
          ?"crypto/sha256"
          ?"fmt"
          ?"io"
          )

          func?main()??{
          ?key?:=?[]byte("1234567890abcdefg")
          ?//?創(chuàng)建hmac?hash對象
          ?hash?:=?hmac.New(sha256.New,?key)
          ?//?寫入字符串計算散列
          ?io.WriteString(hash,?"hi,geek")
          ?//?計算hmac散列
          ?fmt.Printf("%x\n",?hash.Sum(nil))??//?89fda53d5e71e8c87adb15f8bf11c2c931af019a5c040321e243b82a3bb45ee5

          ?hash2?:=?hmac.New(sha256.New,?key)
          ?hash2.Write([]byte("hi,geek"))

          ?fmt.Println(hmac.Equal(hash2.Sum(nil),?hash.Sum(nil)))??//?true
          }

          使用示例

          package?main

          import?(
          ?"crypto/hmac"
          ?"fmt"
          ?"io"
          )

          //?使用sha1的Hmac散列算法
          func?hmacHash(msg?string,?key?string)?(hashData?[]byte)?{
          ?k?:=?[]byte(key)
          ?mac?:=?hmac.New(sha1.New,?k)
          ?io.WriteString(mac,?msg)
          ?hashData?=?mac.Sum(nil)
          ?return
          }

          func?main()?{
          ?msg?:=?"This?is?the?message?to?hash!"
          ?//?hmac
          ?hmacData?:=?hmacHash(msg,?"The?key?string!")
          ?fmt.Printf("HMAC:?%x\n",?hmacData)
          }

          6、哈希函數(shù)的應(yīng)用

          • 用戶密碼的存儲

          • 文件上傳/下載完整性校驗

          • mysql 大字段的快速對比

          • 數(shù)字簽名(區(qū)塊鏈,比特幣)

          示例代碼

          package?main

          import?(
          ?"crypto/md5"
          ?"crypto/sha1"
          ?"encoding/hex"
          ?"fmt"
          )

          func?Sha1(data?string)?string?{
          ?sha1?:=?sha1.New()
          ?sha1.Write([]byte(data))
          ?return?hex.EncodeToString(sha1.Sum(nil))
          }

          func?Md5(data?string)?string?{
          ?md5?:=?md5.New()
          ?md5.Write([]byte(data))
          ?return?hex.EncodeToString(md5.Sum(nil))
          }

          func?main()?{
          ?data?:=?"abcdefg"
          ?fmt.Printf("SHA-1:?%s\n",?Sha1(data))
          ?fmt.Printf("MD5:?%s\n",?Md5(data))
          }

          一個實際的例子,用戶名密碼校驗

          密碼校驗則是一個很常見的問題, 當我們設(shè)計用戶中心時,是一個必不可少的功能, 為了安全,我們都不會保存用戶的明文密碼, 最好的方式就是保存為Hash, 這樣即使是數(shù)據(jù)泄露了,也不會導致用戶的明文密碼泄露(hash的過程是不可逆的)

          示例需求如下

          • 能校驗密碼
          • 用戶可以修改密碼
          • 修改密碼時,禁止使用最近已經(jīng)使用過的密碼
          //?NewHashedPassword?生產(chǎn)hash后的密碼對象
          func?NewHashedPassword(password?string)?(*Password,?error)?{
          ?bytes,?err?:=?bcrypt.GenerateFromPassword([]byte(password),?10)
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?return?&Password{
          ??Password:?string(bytes),
          ??CreateAt:?ftime.Now().Timestamp(),
          ??UpdateAt:?ftime.Now().Timestamp(),
          ?},?nil
          }

          type?Password?struct?{
          ?//?hash過后的密碼
          ?Password?string
          ?//?密碼創(chuàng)建時間
          ?CreateAt?int64
          ?//?密碼更新時間
          ?UpdateAt?int64
          ?//?密碼需要被重置
          ?NeedReset?bool
          ?//?需要重置的原因
          ?ResetReason?string
          ?//?歷史密碼
          ?History?[]string
          ?//?是否過期
          ?IsExpired?bool
          }

          //?Update?更新密碼
          func?(p?*Password)?Update(new?*Password,?maxHistory?uint,?needReset?bool)?{
          ?p.rotaryHistory(maxHistory)
          ?p.Password?=?new.Password
          ?p.NeedReset?=?needReset
          ?p.UpdateAt?=?ftime.Now().Timestamp()
          ?if?!needReset?{
          ??p.ResetReason?=?""
          ?}
          }

          //?IsHistory?檢測是否是歷史密碼
          func?(p?*Password)?IsHistory(password?string)?bool?{
          ?for?_,?pass?:=?range?p.History?{
          ??err?:=?bcrypt.CompareHashAndPassword([]byte(pass),?[]byte(password))
          ??if?err?==?nil?{
          ???return?true
          ??}
          ?}

          ?return?false
          }

          //?HistoryCount?保存了幾個歷史密碼
          func?(p?*Password)?HistoryCount()?int?{
          ?return?len(p.History)
          }

          func?(p?*Password)?rotaryHistory(maxHistory?uint)?{
          ?if?uint(p.HistoryCount())???p.History?=?append(p.History,?p.Password)
          ?}?else?{
          ??remainHistry?:=?p.History[:maxHistory]
          ??p.History?=?[]string{p.Password}
          ??p.History?=?append(p.History,?remainHistry...)
          ?}
          }

          //?CheckPassword?判斷password?是否正確
          func?(p?*Password)?CheckPassword(password?string)?error?{
          ?err?:=?bcrypt.CompareHashAndPassword([]byte(p.Password),?[]byte(password))
          ?if?err?!=?nil?{
          ??return?exception.NewUnauthorized("user?or?password?not?connrect")
          ?}
          ?return?nil
          }

          See you ~

          歡迎進群一起進行技術(shù)交流

          加群方式:公眾號消息私信“加群或加我好友再加群均可

          瀏覽 72
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  另类TS人妖一区二区三 | 台湾成人无码 | 成人激情站,开心五月天 | 亚洲视频免费观看H | 一本色道久久88综合精品看片 |