Golang數據安全與常用加解密算法-對稱加密算法


加密過程的每一步都是可逆的,加密和解密用的是同一組密鑰,異或是最簡單的對稱加密算法

DES

DES數組分級

  • DES(Data Encryption Standard)數據加密標准,是目前最為流行的加密算法之一。
  • 對原始數據(明文)進行分組,每組64位,最后一組不足64位時按一定規則填充。
  • 每一組上單獨施加DES算法。

DES子秘鑰生成

  • 初始密鑰64位,實際有效位56位,每隔7位有一個校驗位
  • 根據初始密鑰生成16個48位的子秘鑰

初始秘鑰【64位】 -> 密鑰置換 -> K0【56位】

置換表

57 49 41 33 25 17 9 1 58 50 42 34 26 18
10 2 59 51 43 35 27 19 11 3 60 52 44 36
63 55 47 39 31 23 15 7 62 54 46 38 30 22
14 6 61 53 45 37 29 21 13 5 28 20 12 4

DES加密過程

S盒替換

輸入48位,輸出32位,各分為8組,每組6位,輸出每組4位。分別在每組上施加S盒替換,一共8個S盒。

分組模式

CBC(Cipher Block Chaining)密文分組組鏈接模式,將當前明文分組與前一個密文分組進行異或運算,然后再進行加密。

第一組的明文,得到了第一組的密文,使用第一組的密文與第二組的明文進行異或運算,然后在進行DES加密算法,得到第二組的密文… … 所以就沒辦法並行執行,加密更加安全,前后組之間相互聯系。

其他分組模式還有BCE、CTR、CFR、OFB

示例代碼:

package main

import (
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"encoding/hex"
	"fmt"
)

// XOR 異或運算加解密
func XOR(plain string, key []byte) string {
	bPlain := []byte(plain)
	bCipher := make([]byte, len(key))
	for i, k := range key {
		bCipher[i] = k ^ bPlain[i]
	}
	cipherText := string(bCipher)
	return cipherText
}

// ZeroPadding 填充
func ZeroPadding(cipherText []byte, blockSize int) []byte {
	padding := blockSize - len(cipherText)%blockSize
	padText := bytes.Repeat([]byte{0}, padding) //剩余用0填充
	return append(cipherText, padText...)

}

// ZeroUnPadding 反填充
func ZeroUnPadding(origData []byte) []byte {
	return bytes.TrimFunc(origData, func(r rune) bool {
		return r == rune(0)
	})
}

// DesEncrypt DES加密,秘鑰必須是64位,所以key必須是長度為8的byte數組
func DesEncrypt(text string, key []byte) (string, error) {
	src := []byte(text)
	block, err := des.NewCipher(key) //用des創建一個加密器cipher
	if err != nil {
		return "", err
	}
	blockSize := block.BlockSize()    //分組的大小,blockSize = 8
	src = ZeroPadding(src, blockSize) //填充
	out := make([]byte, len(src))     //密文和明文的長度一致
	dst := out
	for len(src) > 0 {
		//分組加密
		block.Encrypt(dst, src[:blockSize]) //對src進行加密,加密結果放到dst里
		//移到下一組
		src = src[blockSize:]
		dst = dst[blockSize:]
	}
	return hex.EncodeToString(out), nil
}

// DesDecrypt
func DesDecrypt(text string, key []byte) (string, error) {
	src, err := hex.DecodeString(text) //轉成[]byte
	if err != nil {
		return "", err
	}
	block, err := des.NewCipher(key)
	if err != nil {
		return "", err
	}
	blockSize := block.BlockSize()
	out := make([]byte, len(src))
	dst := out
	for len(src) > 0 {
		//分組解密
		block.Decrypt(dst, src[:blockSize]) //對src進行解密,解密結果放到dst里
		//移到下一組
		src = src[blockSize:]
		dst = dst[blockSize:]
	}
	out = ZeroUnPadding(out) //反填充
	return string(out), nil
}

//DesEncryptCBC
func DesEncryptCBC(text string, key []byte) (string, error) {
	src := []byte(text)
	block, err := des.NewCipher(key) //用des創建一個加密cipher
	if err != nil {
		return "", err
	}
	blockSize := block.BlockSize()                  //分組的大小,blockSize = 8
	src = ZeroPadding(src, blockSize)               //填充
	out := make([]byte, len(src))                   //密文和明文的長度一致
	encrypted := cipher.NewCBCEncrypter(block, key) //CBC分組模式加密
	encrypted.CryptBlocks(out, src)                 //對src進行加密,加密結果放到out里
	return hex.EncodeToString(out), nil
}

// DesDecryptCBC
func DesDecryptCBC(text string, key []byte) (string, error) {
	src, err := hex.DecodeString(text) //轉成[]byte
	if err != nil {
		return "", err
	}
	block, err := des.NewCipher(key)
	if err != nil {
		return "", err
	}

	out := make([]byte, len(src))                   //密文和明文長度一致
	encrypted := cipher.NewCBCDecrypter(block, key) //CBC分組模式解密
	encrypted.CryptBlocks(out, src)                 //對src進行解密,解密結果放到out里
	out = ZeroUnPadding(out)                        //反填充
	return string(out), nil
}

func main() {
	plain := "ABCD"
	key := []byte{1, 2, 3, 4}
	cipherText := XOR(plain, key)
	plain = XOR(cipherText, key)
	fmt.Printf("明文:%s\n", plain)
	fmt.Println("---------------分割線----------------------")

	fmt.Println("Golang crypto package")
	key = []byte("2022aBc!")
	plain = "我們都一樣沒什么不同"

	cipherText, _ = DesEncrypt(plain, key)
	fmt.Printf("DES密文:%s\n", cipherText)
	plain, _ = DesDecrypt(cipherText, key)
	fmt.Printf("DES明文:%s\n", plain)

	cipherText, _ = DesEncryptCBC(plain, key)
	fmt.Printf("DES-CBC密文:%s\n", cipherText)
	plain, _ = DesDecryptCBC(cipherText, key)
	fmt.Printf("DES-CBC明文:%s\n", plain)
}


>>>>>>>>>>output
明文:ABCD
---------------分割線----------------------
Golang crypto package
DES密文:1fa13fa924245362452305714eb960a024c0a393c509e40120fd1f0900c02e68
DES明文:我們都一樣沒什么不同
DES-CBC密文:8f8ad928e0bcf060a5f8711c2f0ff6677714a1b38a56c26489ed50443200eca6
DES-CBC明文:我們都一樣沒什么不同

AES

AES(Advanced Encryption Stadnard)高級加密標准,皆在取代DES。

示例代碼:

package main

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/hex"
	"fmt"
)

// ZeroPadding 填充零
func ZeroPadding(cipherText []byte, blockSize int) []byte {
	padding := blockSize - len(cipherText)%blockSize
	padText := bytes.Repeat([]byte{0}, padding) //剩余用0填充
	return append(cipherText, padText...)

}

// ZeroUnPadding 反填充
func ZeroUnPadding(origData []byte) []byte {
	return bytes.TrimFunc(origData, func(r rune) bool {
		return r == rune(0)
	})
}


func AESEncrypt(text string, key []byte) (string, error) {
	blockSize := aes.BlockSize //AES的分組大小為16位
	src := []byte(text)
	src = ZeroPadding(src, blockSize) //填充
	out := make([]byte, len(src))
	block, err := aes.NewCipher(key) //用aes創建一個加密器cipher
	if err != nil {
		return "", err
	}
	encrypted := cipher.NewCBCEncrypter(block, key) //CBC分組模式加密
	encrypted.CryptBlocks(out, src)                 //對src進行加密,加密結果放到dst里
	return hex.EncodeToString(out), nil
}

func AESDecrypt(text string, key []byte) (string, error) {
	src, err := hex.DecodeString(text) //轉為[]byte
	if err != nil {
		return "", err
	}
	out := make([]byte, len(src))
	block, err := aes.NewCipher(key) //用aes創建一個加密器cipher
	if err != nil {
		return "", err
	}
	decrypted := cipher.NewCBCDecrypter(block, key) //CBC分組模式解密
	decrypted.CryptBlocks(out, src)                 //對src進行解密,解密結果放到dst里
	out = ZeroUnPadding(out)                        //反填充
	return string(out), nil
}

func main() {
	key := []byte("2022aBc!2022aBc!")
	plain := "我們有什么不同"
	cipherText,_ := AESEncrypt(plain, key)
	fmt.Printf("密文:%s\n", cipherText)
	plain, _ = AESDecrypt(cipherText, key)
	fmt.Printf("明文:%s\n", plain)
}

>>>>>>>>>>output
密文:94b14fe8380c20dfe2f3e2964275f47052a177d3280b025d6e9700cac04a5ef8
明文:我們有什么不同


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM