<golang>常用對稱加密DES、3DES具體實現
版權宣告:本文為作者原創,如需轉載,請註明出處
https://blog.csdn.net/weixin_42940826
注:分組加密演算法需要用分組模式的知識,在我上一篇帖子裡有具體介紹,歡迎來戳對稱加密演算法常用的五種分組模式(ECB/CBC/CFB/OFB/CTR)
DES簡介和實現
DES – Data Encryption Standard
(已經被破解不再使用,但是很有研究價值,而且誕生出了3DES還可以使用)
常見問題
Q1 :是不是分組密碼?
A :是, 先對資料進行分組, 然後在加密或解密
Q2:DES的分組長度?
A:8byte == 64bit
Q3: DES的祕鑰長度?
A:56bit祕鑰長度+8bit錯誤檢測標誌位 = 8byte == 64bit
接下來我們使用CBC分組模式實現DES的加密解密(一種常用且需要填充的分組模式)
package main
import (
"bytes"
"crypto/des"
"crypto/cipher"
"fmt"
)
//首先需要一個填充函式,確保長度是模組長度的整數倍
func Padding(blockSize int,plainText []byte)[]byte {
//計算當前明文位元組數除以模組長度的餘數
yu:=len(plainText)%blockSize
//需要填充的長度即為模組長度減去餘數
needlen:=blockSize-yu
//得到填充的字元
//為了方便解密時的去填充操作,我們將填充的字元設定為填充長度
needbytes:=bytes.Repeat([]byte{byte(needlen)},needlen)
newPlaintext:=append(plainText,needbytes...)
return newPlaintext
}
//再來一個解密時所需的去填充函式,和填充函式同理,不做過多註釋
func Unpadding(plainText []byte)[]byte {
needlen:=plainText[len(plainText)-1]
return plainText[:len(plainText)-int(needlen)]
}
//CBC模式下的DES加密函式
func DES_CBC_encrypter(key []byte,plainText []byte)[]byte {
//DES演算法的模組大小為8,這是固定的,不能改變
blockSize:=8
//啟用我們的填充函式,為加密做好準備
newPlaintext:=Padding(blockSize,plainText)
//指定一個DES演算法,需要的引數是祕鑰,祕鑰長度為8位,返回一個cipher.Block介面
block,_:=des.NewCipher(key)
//此函式需要一個iv值,長度要跟祕鑰長度相等,即8位,內容隨意,但解密時需要相同的iv
iv:=[]byte("thisisiv")
//指定CBC的分組模式,所需引數為前面得到的cipher.Block介面,再次返回一個blockmode介面
blockmode:=cipher.NewCBCEncrypter(block,iv)
//演算法和分組模式都指定完畢了,開始計算
//所需兩個引數,一個是用來存放加密後的密文,另一個是填充好了的明文,兩文長度是一樣的
cipherText:=make([]byte,len(newPlaintext))
blockmode.CryptBlocks(cipherText,newPlaintext)
return cipherText
}
func main() {
//設定祕鑰和明文,進行加密呼叫列印到螢幕上
key:=[]byte("thisiske")
plainText:=[]byte("ThisIsPlaintext")
cipherText:=DES_CBC_encrypter(key,plainText)
fmt.Println(cipherText)
}
//執行得到看不懂的結果
以上為DES加密操作,解密操作大同小異,下面直接給出程式碼
func DES_CBC_decrypter(key []byte,cipherText []byte)[]byte{
block,_:=des.NewCipher(key)
//需要和加密時一樣的iv
iv:=[]byte("thisisiv")
blockmode:=cipher.NewCBCDecrypter(block,iv)
plainText:=make([]byte,len(cipherText))
blockmode.CryptBlocks(plainText,cipherText)
//最後不要忘了去填充
return Unpadding(plainText)
}
DES已經可以在短時間內被暴力破解了,所以3DES應運而生
3DES簡介和實現
三重DES (Triple-DES),顧名思義,就是將DES演算法重複三次,所得到的演算法,也叫TDEA,下圖直接明瞭的闡釋了3DES的具體實現方法。
常見問題
Q1:3DES安全嗎?
A:安全, 但是效率低
Q2:是不是分組密碼,需不需要填充?
A:是,需要,DES怎麼填充他還是怎麼填充
Q3:3DES分組長度?
A:8位元組,因為進行三次操作,每次操作內部還是和DES一樣的
Q4:3DES祕鑰長度?
A:24位元組, 在演算法內部會被平均分成3份
程式碼實現,填充函式我們可以直接呼叫上面已經封裝好的Padding,就不重複給出了
package main
import (
"bytes"
"crypto/des"
"crypto/cipher"
"fmt"
)
//首先需要一個填充函式,確保長度是模組長度的整數倍
func Padding(blockSize int,plainText []byte)[]byte {
//計算當前明文位元組數除以模組長度的餘數
yu:=len(plainText)%blockSize
//需要填充的長度即為模組長度減去餘數
needlen:=blockSize-yu
//得到填充的字元
//為了方便解密時的去填充操作,我們將填充的字元設定為填充長度
needbytes:=bytes.Repeat([]byte{byte(needlen)},needlen)
newPlaintext:=append(plainText,needbytes...)
return newPlaintext
}
//再來一個解密時所需的去填充函式,和填充函式同理,不做過多註釋
func Unpadding(plainText []byte)[]byte {
needlen:=plainText[len(plainText)-1]
return plainText[:len(plainText)-int(needlen)]
}
func CBC_3DES_encrypter(key []byte,plainText []byte)[]byte {
BlockSize:=8
newPlaintext:=Padding(BlockSize,plainText)
block,_:=des.NewTripleDESCipher(key)
iv:=[]byte("thisisiv")
blockmode:=cipher.NewCBCEncrypter(block,iv)
cipherText:=make([]byte,len(newPlaintext))
blockmode.CryptBlocks(cipherText,newPlaintext)
return cipherText
}
func CBC_3DES_decrypter(key []byte,cipherText []byte)[]byte {
block,_:=des.NewTripleDESCipher(key)
iv:=[]byte("thisisiv")
blockmode:=cipher.NewCBCDecrypter(block,iv)
buf:=make([]byte,len(cipherText))
blockmode.CryptBlocks(buf,cipherText)
return Unpadding(buf)
}
func main() {
key:=[]byte("TheLengthOfKeyOf3desIs24")
plainText:=[]byte("IamThePlaintext00")
cipherText:=CBC_3DES_encrypter(key,plainText)
fmt.Println(cipherText)
result:=CBC_3DES_decrypter(key,cipherText)
fmt.Println(string(result))
}
其實實現起來和DES的實現沒什麼區別,唯一的區別就是祕鑰的長度為3*8=24
相關連結
對稱加密演算法常用的五種分組模式(ECB/CBC/CFB/OFB/CTR)
CTR分組模式實現的AES加密解密
歡迎交流:)