1. 程式人生 > >常用對稱加密DES、3DES具體實現(go語言)

常用對稱加密DES、3DES具體實現(go語言)

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的具體實現方法。 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

在下個帖子有使用CTR模式實現的AES加密。 歡迎交流:)