常用對稱加密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的具體實現方法。
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加密解密
歡迎交流:)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章