版權聲明:本文爲作者原創,如需轉載,請註明出處
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加密解密
歡迎交流:)