DES--------Golang對稱加密之模式問題實戰
1. 背景
近期專案在對接第三方產品,傳輸過程中涉及到資料加密, 資料加密流程為:
傳送資料DES加密
DES加密後的資料進行base64編碼
傳送,接受資料
接受讀取的資料進行base64解碼
base64解碼完的資料機型DES解密
由於採用golang對接,文件且無說明情況下,預設採用CBC模式加解密,導致很長時間對接不上。
後透過對方Java Demo程式碼檢視得知採用ECB加密模式,Java預設DES演算法使用DES/ECB/PKCS5Padding工作方式,在GO語言中因為ECB的脆弱性,DES的ECB模式是故意不放出來的,但實際情況中有時我們並不需要那麼安全。
DES介紹
DES 使用一個 56 位的金鑰以及附加的 8 位奇偶校驗位,產生最大 64 位的分組大小。這是一個迭代的分組密碼,使用稱為 Feistel 的技術,其中將加密的文字塊分成兩半。使用子金鑰對其中一半應用迴圈功能,然後將輸出與另一半進行"異或"運算;接著交換這兩半,這一過程會繼續下去,但最後一個迴圈不交換。DES 使用 16 個迴圈,使用異或,置換,代換,移位操作四種基本運算。
DES常見加密模式
CBC(加密分組連結模式)
密文分組連結方式,這是golang和.NET封裝的DES演算法的預設模式,它比較麻煩,加密步驟如下:
首先將資料按照8個位元組一組進行分組得到D1D2......Dn(若資料不是8的整數倍,就涉及到資料補位了)
第一組資料D1與向量I異或後的結果進行DES加密得到第一組密文C1(注意:這裡有向量I的說法,ECB模式下沒有使用向量I)
第二組資料D2與第一組的加密結果C1異或以後的結果進行DES加密,得到第二組密文C2
之後的資料以此類推,得到Cn
按順序連為C1C2C3......Cn即為加密結果。
資料補位一般有NoPadding和PKCS7Padding(JAVA中是PKCS5Padding)填充方式,PKCS7Padding和PKCS5Padding實際只是協議不一樣,根據相關資料說明:PKCS5Padding明確定義了加密塊是8位元組,PKCS7Padding加密快可以是1-255之間。但是封裝的DES演算法預設都是8位元組,所以可以認為他們一樣。資料補位實際是在資料不滿8位元組的倍數,才補充到8位元組的倍數的填充過程。
NoPadding填充方式:演算法本身不填充,比如.NET的padding提供了有None,Zeros方式,分別為不填充和填充0的方式。
PKCS7Padding(PKCS5Padding)填充方式:為.NET和JAVA的預設填充方式,對加密資料位元組長度對8取餘為r,如r大於0,則補8-r個位元組,位元組為8-r的值;如果r等於0,則補8個位元組8。比如:
加密字串為為AAA,則補位為AAA55555;加密字串為BBBBBB,則補位為BBBBBB22;加密字串為CCCCCCCC,則補位為CCCCCCCC88888888。
ECB(電子密碼本模式)
電子密本方式,這是JAVA封裝的DES演算法的預設模式,就是將資料按照8個位元組一段進行DES加密或解密得到一段8個位元組的密文或者明文,最後一段不足8個位元組,則補足8個位元組(注意:這裡就涉及到資料補位了)進行計算,之後按照順序將計算所得的資料連在一起即可,各段資料之間互不影響。
CFB(加密反饋模式)
加密反饋模式克服了需要等待8個位元組才能加密的缺點,它採用了分組密碼作為流密碼的金鑰流生成器;
OFB(輸出反饋模式)
與CFB模式不同之處在於, 加密位移暫存器與密文無關了,僅與加密key和加密演算法有關;
做法是不再把密文輸入到加密移位暫存器,而是把輸出的分組密文(Oi)輸入到一位暫存器;
DES加密之golang的CBC和ECB模式程式碼實現
CBC和ECB模式加密
func DesECBEncrypt(data, key []byte)([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
bs := block.BlockSize()
data = PKCS5Padding(data, bs)
if len(data)%bs != 0 {
return nil, errors.New("Need a multiple of the blocksize")
}
out := make([]byte, len(data))
dst := out
for len(data) > 0 {
block.Encrypt(dst, data[:bs])
data = data[bs:]
dst = dst[bs:]
}
return out, nil
}
func DesCBCEncrypt(origData, key []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
origData = PKCS5Padding(origData, block.BlockSize())
// origData = ZeroPadding(origData, block.BlockSize())
blockMode := cipher.NewCBCEncrypter(block, key)
crypted := make([]byte, len(origData))
// 根據CryptBlocks方法的說明,如下方式初始化crypted也可以
// crypted := origData
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
CBC和ECB模式解密
func DesECBDecrypt(data, key []byte)([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
bs := block.BlockSize()
if len(data)%bs != 0 {
return nil, errors.New("crypto/cipher: input not full blocks")
}
out := make([]byte, len(data))
dst := out
for len(data) > 0 {
block.Decrypt(dst, data[:bs])
data = data[bs:]
dst = dst[bs:]
}
out = PKCS5UnPadding(out)
return out, nil
}
func DesCBCDecrypt(crypted, key []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
blockMode := cipher.NewCBCDecrypter(block, key)
//origData := make([]byte, len(crypted))
origData := crypted
blockMode.CryptBlocks(origData, crypted)
//origData = PKCS5UnPadding(origData)
origData = PKCS5UnPadding(origData)
return origData, nil
}
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
總結
以需求驅動技術,技術本身沒有優略之分,只有業務之分。
©著作權歸作者所有:來自51CTO部落格作者asd1123509133的原創作品,如需轉載,請註明出處,否則將追究法律責任
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3244/viewspace-2819617/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- .NET Core加解密實戰系列之——對稱加密演算法解密加密演算法
- 對稱加密與非對稱加密加密
- 資料加密(對稱加密和非對稱加密)加密
- 密碼學之對稱加密密碼學加密
- 編碼與加密(對稱加密與非對稱加密)加密
- 對稱加密、非對稱加密、RSA(總結)加密
- https中的對稱加密和非對稱加密HTTP加密
- 對稱加密和非對稱加密(一)初步理解加密
- 加密原理詳解:對稱式加密VS非對稱式加密加密
- 一文搞懂對稱加密:加密演算法、工作模式、填充方式、程式碼實現加密演算法模式
- golang 中,非對稱加密的實現Golang加密
- 對稱加密體系加密
- golang 中,對稱加密的程式碼實現Golang加密
- 非對稱加密與 jwt加密JWT
- RSA 非對稱加密&解密加密解密
- 非對稱加密體系加密
- Linux SSH是什麼?對稱加密和非對稱加密有何區別?Linux加密
- Linux系統中對稱加密和非對稱加密區別是什麼?Linux加密
- Flink實戰之寫Hive效能問題Hive
- .Net微服務實戰之必須得面對的分散式問題微服務分散式
- 聊聊對稱/非對稱加密在HTTPS中的應用加密HTTP
- 對稱、非對稱的加密技術是如何對網站資料進行雙重加密?加密網站
- Flutter實戰之開發問題集(一)Flutter
- 非對稱加密--RSA原理淺析加密
- MSSQL-最佳實踐-使用非對稱金鑰實現列加密SQL加密
- 三次函式的對稱中心問題函式
- golang 密碼學-1. 對稱加密Golang密碼學加密
- 理解區塊鏈的非對稱加密區塊鏈加密
- 前後端(PHP)使用AES對稱加密後端PHP加密
- 非對稱加密和數字證書加密
- 非對稱加密技術:共享祕鑰加密
- 非對稱加密和證書總結加密
- 非對稱加密演算法的思考加密演算法
- 應用加密1;非對稱加密演算法揭祕加密演算法
- 前後端資料加密傳輸 RSA非對稱加密後端加密
- 對稱加密、非對稱加密、RSA、訊息摘要、數字簽名、數字證書與HTTPS簡介加密HTTP
- 第四篇:非對稱加密及RSA加密演算法加密演算法
- RSA非對稱加密演算法淺析加密演算法