密码技术--对称加密算法及Go语言应用
對稱加密算法
DES
Data Encryption Standard (數據加密標準)是1977年美國聯邦信息處理標準(FIPS)中所采用的一種對稱密碼。DES一直以來被美國以及其他國家的政府和銀行等廣泛應用,然而,隨著計算機的進步,現在DES已經能夠本暴力破解,強度大不如以前了。
RSA公司舉辦過破譯DES密鑰的比賽(DESChallenge),比賽的結果為:
- 1977年比賽中用了96天破解
- 1998年第一次比賽用了41天破解
- 1998年第二次比賽用了56小時
- 1999年第三次比賽中只用了22小時15分鐘就被破解了
由于DES的密文可以在短時間內被破解,因此除了它來解密以前的密文外,現在我們不應該使用該算法了,不安全。
DES的加密解密
DES時一種將64比特的明文加密成64比特的密文的對稱密碼算法,它的密鑰長度是56比特,盡管從規格上來說,DES的密鑰長度是64比特,但由于每隔7比特會設置一個用于錯誤檢查的比特,因此實質上其密鑰長度是56比特。
總結:
- 現在使用DES方式加密,數據還安全嗎?
- 不安全,已經被破解
- 是不是分組密碼?
- 是,先對數據進行分組,然后再加密或解密
- DES的分組長度?
- 8byte==64bit
- DES 的秘鑰長度?
- 56bit秘鑰長度+8bit錯誤檢查標志位=64bit==8byte
3DES
Triple-DES,三重DES–使用DES三次加密
總結:
- 3DES安全嗎?
- 安全,但是效率低
- 算法描述?
- 進行了三次DES加密
- 是不是分組算法?
- 是
- 3DES分組長度?
- 8byte
- 3DES秘鑰長度?
- 24byte,在算法內部會被平均分成3份,目的是兼容DES
- 3DES加密過程?
- 秘鑰1->加密->,秘鑰2->解密,秘鑰3->加密
- 3DES解密過程?
- 秘鑰1->解密->,秘鑰2->加密,秘鑰3->解密
DES-CBC模式加解密Go實現
package mainimport ("crypto/cipher""crypto/des" )//明文數據填充 func paddingLastGroup(plainText []byte, blockSize int) []byte {//1.計算最后一個分組中明文后需要填充的字節數padNum := blockSize - len(plainText)%blockSize//2.將字節數轉換為byte類型char := []byte{byte(padNum)}//3.創建切片并初始化newPlain := bytes.Repeat(char, padNum)//4.將填充數據追加到原始數據后newText := append(plainText, newPlain...)return newText }//去掉明文后面的填充數據 func unpaddingLastGroup(plainText []byte) []byte {//1.拿到切片中的最后一個字節length := len(plainText)lastChar := plainText[length-1]//2.將最后一個數據轉換為整數number := int(lastChar)return plainText[:length-number] }//des加密 func desEncrypt(plainText, key []byte) []byte {//1.建立一個底層使用的des密碼接口block, err := des.NewCipher(key)if err != nil {panic(err)}//2.填充明文數據(這里必須填充,不管原始明文是否能被塊長度整除)groupData := paddingLastGroup(plainText, block.BlockSize())//3.選擇加密模式iv := []byte("12345678")blockMode := cipher.NewCBCEncrypter(block, iv)//4.加密cipherText := make([]byte, len(groupData))blockMode.CryptBlocks(cipherText, groupData)//blockMode.CryptBlocks(groupData, groupData) //這樣也可以,官方文檔中說明傳入傳出參數可指向同一地址return cipherText }//des解密 func desDecrypt(cipherText, key []byte) []byte {//1.創建一個des底層密碼接口block, err := des.NewCipher(key)if err != nil {panic(err)}//2.選擇解密模式iv := []byte("12345678") //初始化向量必須和加密時的一樣blockMode := cipher.NewCBCDecrypter(block, iv)//3.解密padText := make([]byte, len(cipherText))blockMode.CryptBlocks(padText, cipherText)//4.去填充數據plainText := unpaddingLastGroup(padText)return plainText }func main(){fmt.Println("des 加解密")key := []byte("1q2w3e4r")src := []byte("DES --Data Encryption Standard (數據加密標準)是1977年美國聯邦信息處理標準(FIPS)中所采用的一種對稱密碼。DES一直以來被美國以及其他國家的政府和銀行等廣泛應用,然而,隨著計算機的進步,現在DES已經能夠本暴力破解,強度大不如以前了。由于DES的密文可以在短時間內被破解,因此除了它來解密以前的密文外,現在我們不應該使用該算法了,不安全。")cipherText := desEncrypt(src, key)plainText := desDecrypt(cipherText, key)fmt.Println("解密后的數據為:", string(plainText)) }AES
Advanced Encryption Standard(高級加密標準),AES是取代DES的一種對稱密碼算法,底層算法為Rijndael,該底層算法是有比利時密碼學家設計的分組密碼算法。
Rijndael的分組長度為128比特,密鑰長度可以以32比特為單位在128比特到256比特的范圍內進行選擇,在AES的規格中,密鑰長度只有128、192、256比特三種
128bit = 16字節
192bit = 24字節
256bit = 32字節
在go提供的接口中只支持16字節長度的密鑰長度
總結:
- AES安全嗎?
- 安全,效率高,推薦使用
- 是不是分組密碼?
- 是
- AES分組長度?
- 128bit = 16字節
- AES密鑰長度?
- 128bit = 16字節
- 192bit = 24字節
- 256bit = 32字節
- 在go提供的接口中只支持16字節
AES-CTR模式加解密Go實現
package mainimport ("crypto/aes""crypto/cipher" )//aes加密 func aesEncrypt(plainText, key []byte) []byte {//1.建立一個底層使用的aes密碼接口block, err := aes.NewCipher(key)if err != nil {panic(err)}//2.ctr模式不需要數據填充//3.選擇加密模式iv := []byte("12345678qwertyui") //不需要初始化向量,go接口中的iv可以理解為隨機數種子,iv的長度等于明文分組長度,并不是真正的初始化向量stream := cipher.NewCTR(block, iv)//4.加密stream.XORKeyStream(plainText, plainText)return plainText }//aes解密 func aesDecrypt(cipherText, key []byte) []byte {//1.創建一個aes底層密碼接口block, err := aes.NewCipher(key)if err != nil {panic(err)}//2.選擇解密模式iv := []byte("12345678qwertyui") //隨機數種子,長度為16位stream := cipher.NewCTR(block, iv)//3.解密padText := make([]byte, len(cipherText))stream.XORKeyStream(padText, cipherText)return padText }func main(){fmt.Println("aes 加解密")key := []byte("1q2w3e4r")src := []byte("AES --Advanced Encryption Standard(高級加密標準)\nAES是取代DES的一種對稱密碼算法,底層算法為Rijndael,該底層算法是有比利時密碼學家設計的分組密碼算法。\nRijndael的分組長度為128比特,密鑰長度可以以32比特為單位在128比特到256比特的范圍內進行選擇,在AES的規格中,密鑰長度只有128、192、256比特三種,在go提供的接口中只支持16字節長度的密鑰長度,加密和解密的函數接口是一個,原因是異或一次就是加密,異或兩次就是解密,因此沒必要實現為兩個接口")cipherText := desEncrypt(src, key)plainText := desDecrypt(cipherText, key)fmt.Println("解密后的數據為:", string(plainText)) }總結
以上是生活随笔為你收集整理的密码技术--对称加密算法及Go语言应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kubernetes中部署Docker
- 下一篇: 密码技术--非对称加密算法及Go语言应用