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
明文:我们有什么不同
posted @ 2022-02-14 23:34  自己有自己的调调、  阅读(802)  评论(7编辑  收藏  举报