<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與對稱加密

          共 6816字,需瀏覽 14分鐘

           ·

          2021-12-23 08:04

          目錄

          • 1、對稱加密介紹

          • 2、DES

            • 2.1 概述

            • 2.2 主要思路

            • 2.3 DES 子密鑰生成

            • 2.4 DES 加密過程

            • 2.5 使用示例

            • 2.6 分組模式

          • 3、AES

          • 4、CBC


          1、對稱加密介紹

          對稱加密算法用來對敏感數(shù)據(jù)等信息進行加密,常用的算法包括:

          • DES(Data Encryption Standard):數(shù)據(jù)加密標準,速度較快,適用于加密大量數(shù)據(jù)的場合
          • 3DES(Triple DES):是基于DES,對一塊數(shù)據(jù)用三個不同的密鑰進行三次加密,強度更高
          • AES(Advanced Encryption Standard):高級加密標準,是下一代的加密算法標準,速度快,安全級別高
          • CBC 分組加密的四種模式之一ECB、CBC、CFB、OFB

          對稱加密又分為分組加密和序列密碼

          • 分組密碼,也叫塊加密block cyphers,一次加密明文中的一個塊。是將明文按一定的位長分組,明文組經(jīng)過加密運算得到密文組,密文組經(jīng)過解密運算(加密運算的逆運算),還原成明文組

          • 序列密碼,也叫流加密stream cyphers,一次加密明文中的一個位。是指利用少量的密鑰(制亂元素)通過某種復(fù)雜的運算(密碼算法)產(chǎn)生大量的偽隨機位流,用于對明文位流的加密

          對稱加密的特點

          • 加密過程每一步都是可逆的

          • 加密和解密用的是同一組密鑰

          2、DES

          2.1 概述

          DES(Data Encryption Standard)數(shù)據(jù)加密標準,是目前最為流行的加密算法之一 DES 是一種使用密鑰加密的塊算法,1977年被美國聯(lián)邦政府的國家標準局確定為聯(lián)邦資料處理標準FIPS,并授權(quán)在非密級政府通信中使用,隨后該算法在國際上廣泛流傳開來

          AES 與 3DES 的比較

          算法名稱算法類型密鑰長度速度解密時間(建設(shè)機器每秒嘗試 255 個密鑰)資源消耗
          AES對稱 block 密碼128、192、256 位1490000 億年
          3DES對稱 feistel 密碼112 位或 168 位46 億年

          破解歷史

          歷史上有三次對DES有影響的攻擊實驗。1997年,利用當(dāng)時各國 7萬臺計算機,歷時96天破解了DES的密鑰。1998年,電子邊境基金會(EFF)用25萬美元制造的專用計算機,用56小時破解了DES的密鑰。1999 年,EFF22小時15分完成了破解工作

          2.2 主要思路

          對原始數(shù)據(jù)(明文)進行分組,每組64bit,最后一組不足64位時按一定規(guī)則填充,每一組上單獨施加DES算法

          2.3 DES 子密鑰生成

          • 第一步

          初始密鑰64位,實際有效位56位,每隔7位有一個校驗位 根據(jù)初始密鑰生成1648位的字密鑰

          密鑰置換(打散),64——>56

          例如,第57位放在第1個位置,第49位放在第2個位置,將順序打亂并去除了校驗位

          • 第二步

          左旋右旋,再次置換 56——>48

          2.4 DES 加密過程

          明文——>初始置換——>L0(32位)、R0(32位)

          S盒替換的邏輯 輸入48位,輸出32位,各分為8組,輸入每組6位,輸出每組4位 分別在每組上施加S盒替換,一共8S

          合并 L16(32位)、R16(32位)——>合并——>最終置換——>密文(64位)

          2.5 使用示例

          /DesEncrypt?DES加密
          //密鑰必須是64位,所以key必須是長度為8的byte數(shù)組
          func?DesEncrypt(text?string,?key?[]byte)?(string,?error)?{
          ?if?len(key)?!=?8?{
          ??return?"",?fmt.Errorf("DES加密算法要求key必須是64位bit")
          ?}
          ?block,?err?:=?des.NewCipher(key)?//用des創(chuàng)建一個加密器cipher
          ?if?err?!=?nil?{
          ??return?"",?err
          ?}
          ?src?:=?[]byte(text)
          ?blockSize?:=?block.BlockSize()???????????//分組的大小,blockSize=8
          ?src?=?common.ZeroPadding(src,?blockSize)?//填充成64位整倍數(shù)

          ?out?:=?make([]byte,?len(src))?//密文和明文的長度一致
          ?dst?:=?out
          ?for?len(src)?>?0?{
          ??//分組加密
          ??block.Encrypt(dst,?src[:blockSize])?//對src進行加密,加密結(jié)果放到dst里
          ??//移到下一組
          ??src?=?src[blockSize:]
          ??dst?=?dst[blockSize:]
          ?}
          ?return?hex.EncodeToString(out),?nil
          }

          //DesDecrypt?DES解密
          //密鑰必須是64位,所以key必須是長度為8的byte數(shù)組
          func?DesDecrypt(text?string,?key?[]byte)?(string,?error)?{
          ?src,?err?:=?hex.DecodeString(text)?//轉(zhuǎn)成[]byte
          ?if?err?!=?nil?{
          ??return?"",?err
          ?}
          ?block,?err?:=?des.NewCipher(key)
          ?if?err?!=?nil?{
          ??return?"",?err
          ?}

          ?blockSize?:=?block.BlockSize()
          ?out?:=?make([]byte,?len(src))
          ?dst?:=?out
          ?for?len(src)?>?0?{
          ??//分組解密
          ??block.Decrypt(dst,?src[:blockSize])
          ??src?=?src[blockSize:]
          ??dst?=?dst[blockSize:]
          ?}
          ?out?=?common.ZeroUnPadding(out)?//反填充
          ?return?string(out),?nil
          }

          2.6 分組模式

          • CBC(Cipher Block Chaining)密文分組鏈接模式,將當(dāng)前明文分組與前一個密文分組進行異或運算,然后再進行加密
          • 其他分組模式還有 ECB、CTR、CFR、OFB

          分組模式使用示例

          func?DesEncryptCBC(text?string,?key?[]byte)?(string,?error)?{
          ?src?:=?[]byte(text)
          ?block,?err?:=?des.NewCipher(key)?//用des創(chuàng)建一個加密器cipher
          ?if?err?!=?nil?{
          ??return?"",?err
          ?}
          ?blockSize?:=?block.BlockSize()???????????//分組的大小,blockSize=8
          ?src?=?common.ZeroPadding(src,?blockSize)?//填充

          ?out?:=?make([]byte,?len(src))???????????????????//密文和明文的長度一致
          ?encrypter?:=?cipher.NewCBCEncrypter(block,?key)?//CBC分組模式加密
          ?encrypter.CryptBlocks(out,?src)
          ?return?hex.EncodeToString(out),?nil
          }

          func?DesDecryptCBC(text?string,?key?[]byte)?(string,?error)?{
          ?src,?err?:=?hex.DecodeString(text)?//轉(zhuǎn)成[]byte
          ?if?err?!=?nil?{
          ??return?"",?err
          ?}
          ?block,?err?:=?des.NewCipher(key)
          ?if?err?!=?nil?{
          ??return?"",?err
          ?}

          ?out?:=?make([]byte,?len(src))???????????????????//密文和明文的長度一致
          ?encrypter?:=?cipher.NewCBCDecrypter(block,?key)?//CBC分組模式解密
          ?encrypter.CryptBlocks(out,?src)
          ?out?=?common.ZeroUnPadding(out)?//反填充
          ?return?string(out),?nil
          }

          3、AES

          AES(Advanced Encryption Standard)高級加密標準,旨在取代DES

          200010月,NIST(美國國家標準和技術(shù)協(xié)會)宣布通過從15種侯選算法中選出的一項新的密匙加密標準。Rijndael被選中成為將來的AES。Rijndael是在1999年下半年,由研究員Joan DaemenVincent Rijmen創(chuàng)建的。AES正日益成為加密各種形式的電子數(shù)據(jù)的實際標準 并于2002526日制定了新的高級加密標準AES規(guī)范

          算法原理

          AES算法基于排列和置換運算。排列是對數(shù)據(jù)重新進行安排,置換是將一個數(shù)據(jù)單元替換為另一個。AES使用幾種不同的方法來執(zhí)行排列和置換運算。AES是一個迭代的、對稱密鑰分組的密碼,它可以使用128、192256位密鑰,并且用128位(16字節(jié))分組加密和解密數(shù)據(jù)。與公共密鑰密碼使用密鑰對不同,對稱密鑰密碼使用相同的密鑰加密和解密數(shù)據(jù)。通過分組密碼返回的加密數(shù)據(jù)的位數(shù)與輸入數(shù)據(jù)相同。迭代加密使用一個循環(huán)結(jié)構(gòu),在該循環(huán)中重復(fù)置換和替換輸入數(shù)據(jù)

          綜上看來AES安全度最高, 基本現(xiàn)狀就是AES已經(jīng)替代DES成為新一代對稱加密的標準

          AES使用示例

          package?main
          import?(
          ?"crypto/aes"
          ?"crypto/cipher"
          ?"fmt"
          )
          var?commonIV?=?[]byte{0x00,?0x01,?0x02,?0x03,?0x04,?0x05,?0x06,?0x07,?0x08,?0x09,?0x0a,?0x0b,?0x0c,?0x0d,?0x0e,?0x0f}
          func?encrypt(plainText?string,?keyText?string)?(cipherByte?[]byte,?err?error)?{
          ?//?轉(zhuǎn)換成字節(jié)數(shù)據(jù),?方便加密
          ?plainByte?:=?[]byte(plainText)
          ?keyByte?:=?[]byte(keyText)
          ?//?創(chuàng)建加密算法aes
          ?c,?err?:=?aes.NewCipher(keyByte)
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}
          ?//加密字符串
          ?cfb?:=?cipher.NewCFBEncrypter(c,?commonIV)
          ?cipherByte?=?make([]byte,?len(plainByte))
          ?cfb.XORKeyStream(cipherByte,?plainByte)
          ?return
          }
          func?decrypt(cipherByte?[]byte,?keyText?string)?(plainText?string,?err?error)?{
          ?//?轉(zhuǎn)換成字節(jié)數(shù)據(jù),?方便加密
          ?keyByte?:=?[]byte(keyText)
          ?//?創(chuàng)建加密算法aes
          ?c,?err?:=?aes.NewCipher(keyByte)
          ?if?err?!=?nil?{
          ??return?"",?err
          ?}
          ?//?解密字符串
          ?cfbdec?:=?cipher.NewCFBDecrypter(c,?commonIV)
          ?plainByte?:=?make([]byte,?len(cipherByte))
          ?cfbdec.XORKeyStream(plainByte,?cipherByte)
          ?plainText?=?string(plainByte)
          ?return
          }
          func?main()?{
          ?plain?:=?"The?text?need?to?be?encrypt."
          ?//?AES?規(guī)定有3種長度的key:?16,?24,?32分別對應(yīng)AES-128,?AES-192,?or?AES-256
          ?key?:=?"abcdefgehjhijkmlkjjwwoew"
          ?//?加密
          ?cipherByte,?err?:=?encrypt(plain,?key)
          ?if?err?!=?nil?{
          ??fmt.Println(err)
          ?}
          ?fmt.Printf("%s?==>?%x\n",?plain,?cipherByte)
          ?//?解密
          ?plainText,?err?:=?decrypt(cipherByte,?key)
          ?if?err?!=?nil?{
          ??fmt.Println(err)
          ?}
          ?fmt.Printf("%x?==>?%s\n",?cipherByte,?plainText)
          }

          4、CBC

          分組密碼,也叫塊加密block cyphers,一次加密明文中的一個塊。是將明文按一定的位長分組,明文組經(jīng)過加密運算得到密文組,密文組經(jīng)過解密運算(加密運算的逆運算),還原成明文組。序列密碼,也叫流加密stream cyphers,一次加密明文中的一個位。是指利用少量的密鑰(制亂元素)通過某種復(fù)雜的運算(密碼算法)產(chǎn)生大量的偽隨機位流,用于對明文位流的加密。解密是指用同樣的密鑰和密碼算法及與加密相同的偽隨機位流,用以還原明文位流

          分組加密算法中,有ECB,CBC,CFB,OFB這幾種算法模式, 我們介紹其中常用的一種CBC

          CBC(Cipher Block Chaining)密文分組鏈接方式

          加密步驟如下:

          • 首先將數(shù)據(jù)按照 8 個字節(jié)一組進行分組得到D1D2......Dn(若數(shù)據(jù)不是 8 的整數(shù)倍,用指定的PADDING數(shù)據(jù)補位)
          • 第一組數(shù)據(jù)D1與初始化向量 I 異或后的結(jié)果進行DES加密得到第一組密文C1(初始化向量 I 為全零)
          • 第二組數(shù)據(jù)D2與第一組的加密結(jié)果C1異或以后的結(jié)果進行DES加密,得到第二組密文C2
          • 之后的數(shù)據(jù)以此類推,得到Cn
          • 按順序連為C1C2C3......Cn即為加密結(jié)果
          //?aesCBCEncrypt?aes加密,填充秘鑰key的16位,24,32分別對應(yīng)AES-128,?AES-192,?or?AES-256.
          func?aesCBCEncrypt(rawData,?key?[]byte)?([]byte,?error)?{
          ?block,?err?:=?aes.NewCipher(key)
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?//填充原文
          ?blockSize?:=?block.BlockSize()
          ?rawData?=?pkcs7Padding(rawData,?blockSize)
          ?//初始向量IV必須是唯一,但不需要保密
          ?cipherText?:=?make([]byte,?blockSize+len(rawData))
          ?//block大小?16
          ?iv?:=?cipherText[:blockSize]
          ?if?_,?err?:=?io.ReadFull(rand.Reader,?iv);?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?//block大小和初始向量大小一定要一致
          ?mode?:=?cipher.NewCBCEncrypter(block,?iv)
          ?mode.CryptBlocks(cipherText[blockSize:],?rawData)

          ?return?cipherText,?nil
          }

          解密是加密的逆過程,步驟如下:

          • 首先將數(shù)據(jù)按照8個字節(jié)一組進行分組得到C1C2C3......Cn
          • 將第一組數(shù)據(jù)進行解密后與初始化向量I進行異或得到第一組明文D1(注意:一定是先解密再異或)
          • 將第二組數(shù)據(jù)C2進行解密后與第一組密文數(shù)據(jù)進行異或得到第二組數(shù)據(jù)D2
          • 之后依此類推,得到Dn
          • 按順序連為D1D2D3......Dn即為解密結(jié)果
          func?aesCBCDecrypt(encryptData,?key?[]byte)?([]byte,?error)?{
          ?block,?err?:=?aes.NewCipher(key)
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?blockSize?:=?block.BlockSize()

          ?if?len(encryptData)???return?nil,?errors.New("ciphertext?too?short")
          ?}
          ?iv?:=?encryptData[:blockSize]
          ?encryptData?=?encryptData[blockSize:]

          ?//?CBC?mode?always?works?in?whole?blocks.
          ?if?len(encryptData)%blockSize?!=?0?{
          ??return?nil,?errors.New("ciphertext?is?not?a?multiple?of?the?block?size")
          ?}

          ?mode?:=?cipher.NewCBCDecrypter(block,?iv)

          ?//?CryptBlocks?can?work?in-place?if?the?two?arguments?are?the?same.
          ?mode.CryptBlocks(encryptData,?encryptData)
          ?//解填充
          ?encryptData?=?pkcs7UnPadding(encryptData)
          ?return?encryptData,?nil
          }

          這里要注意的是,解密的結(jié)果并不一定是我們原來的加密數(shù)據(jù),可能還含有補位,一定要把補位去掉才是原來的數(shù)據(jù)

          特點:

          • 不容易主動攻擊,安全性好于ECB,適合傳輸長度長的報文,是SSL、IPSec的標準。每個密文塊依賴于所有的信息塊, 明文消息中一個改變會影響所有密文塊
          • 發(fā)送方和接收方都需要知道初始化向量
          • 加密過程是串行的,無法被并行化(在解密時,從兩個鄰接的密文塊中即可得到一個平文塊。因此,解密過程可以被并行化)

          See you ~

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

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

          瀏覽 70
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  东方AV100在线观看 | 白丝影院| 亚洲AV秘 无码一区二区三竹菊 | 无码一级毛片免费视频播放 | 日本爱爱激情网 |