Golang加密解密算法

流转 Lv3

md5 加密——不可逆

MD5信息摘要算法是一种被广泛使用的密码散列函数,可以产生出一个128位(16进制,32个字符)的散列值(hash value),用于确保信息传输完整一致。

1
2
3
4
5
import (
"crypto/md5"
"encoding/hex"
"fmt"
)

第一种

1
2
3
4
5
6
7
// MD5Str md5验证
func MD5Str(src string) string {
h := md5.New()
h.Write([]byte(src)) // 需要加密的字符串为
fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}

第二种

1
2
3
4
// MD5Str2 md5验证
func MD5Str2(src string) string {
return fmt.Sprintf("%x", md5.Sum([]byte(src)))
}

hmacsha 加密——不可逆

HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,
它通过一个标准算法,在计算哈希的过程中,把key混入计算过程中。
和我们自定义的加salt算法不同,Hmac算法针对所有哈希算法都通用,无论是MD5还是SHA-1。采用Hmac替代我们自己的salt算法,可以使程序算法更标准化,也更安全。

hmac-md5加密

1
2
3
4
5
6
7
8
9
10
11
12
//key随意设置 data 要加密数据

func Hmac(key, data string) string {
// 创建对应的md5哈希加密算法
hash:= hmac.New(md5.New, []byte(key))

hash.Write([]byte(data))

return hex.EncodeToString(hash.Sum([]byte("")))

}

hamacsha1 加密

1
2
3
4
5
6
// HmacSha1 hmacSha1加密 key随意设置 data 要加密数据
func HmacSha1(src, key string) string {
m := hmac.New(sha1.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}

hamacsha 256 加密

1
2
3
4
5
6
// HmacSHA256 hmacSha256验证  key随意设置 data 要加密数据
func HmacSHA256(key, src string) string {
m := hmac.New(sha256.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}

hmacsha512加密

1
2
3
4
5
6
// HmacSHA512 hmacSha512验证
func HmacSHA512(key, src string) string {
m := hmac.New(sha512.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}

hamasha 调用

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

import (
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"fmt"
)

// Hmac hmac验证 key随意设置 data 要加密数据
func Hmac(key, data string) string {

hash := hmac.New(md5.New, []byte(key)) // 创建对应的md5哈希加密算法

hash.Write([]byte(data))

return hex.EncodeToString(hash.Sum([]byte("")))

}

// HmacSHA256 hmacSha256加密 key随意设置 data 要加密数据
func HmacSHA256(key, src string) string {
m := hmac.New(sha256.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}

// HmacSHA512 hmacSha512加密 key随意设置 data 要加密数据
func HmacSHA512(key, src string) string {
m := hmac.New(sha512.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}

// HmacSha1 hmacSha1加密 key随意设置 data 要加密数据
func HmacSha1(src, key string) string {
m := hmac.New(sha1.New, []byte(key))
m.Write([]byte(src))
return hex.EncodeToString(m.Sum(nil))
}

// SHA256Str sha256加密
func SHA256Str(src string) string {
h := sha256.New()
h.Write([]byte(src)) // 需要加密的字符串为
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}

func main() {
hmac_ := Hmac("hybpjx", "始識")
hamcsha1 := HmacSha1("hybpjx", "始識")
hamcsha256 := HmacSHA256("hybpjx", "始識")
hamacsha512 := HmacSHA512("hybpjx", "始識")
fmt.Println(hmac_)
fmt.Println(hamcsha1)
fmt.Println(hamcsha256)
fmt.Println(hamacsha512)
}

结果

d8801f70df7891764116e1ac003f7189

60d68e01c8a86f3b87e4e147e9f0fadce2a69661

b3f8ddf991288036864761a55046877adfe4f78ec9a89bb63932af92689b139f

b9b1fca0fe91522482ee1b2161e57d67482af6ef371614365b918c31ce774f9126ed627e378a063145f404ff2de7bd84f8e4798c385662ef4749e58e9209ca63

Sha 加密——不可逆

sha1

SHA-1可以生成一个被称为消息摘要的160位(20字节)散列值,散列值通常的呈现形式为40个十六进制数。

1
2
3
4
5
func Sha1(data string) string {
sha1_ := sha1.New()
sha1_.Write([]byte(data))
return hex.EncodeToString(sha1_.Sum([]byte("")))
}

sha256

SHA256算法使用的哈希值长度是256位。这是一个抽象类。此类的唯一实现是SHA256Managed。

1
2
3
4
5
6
7
8
// SHA256 sha256加密
func SHA256(src string) string {
h := sha256.New()
// 需要加密的字符串为
h.Write([]byte(src))
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}

sha512

SHA (Secure Hash Algorithm,译作安全散列算法) 是美国国家安全局 (NSA) 设计,美国国家标准与技术研究院 (NIST) 发布的一系列密码散列函数。

1
2
3
4
5
6
7
8
// SHA512 sha512加密
func SHA512(src string) string {
h := sha512.New()
// 需要加密的字符串为
h.Write([]byte(src))
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}

sha调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package main

import (
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"fmt"
)

func Sha1(data string) string {
sha1_ := sha1.New()
sha1_.Write([]byte(data))
return hex.EncodeToString(sha1_.Sum([]byte("")))
}

// SHA256 sha256加密
func SHA256(src string) string {
h := sha256.New()
// 需要加密的字符串为
h.Write([]byte(src))
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}

// SHA512 sha512加密
func SHA512(src string) string {
h := sha512.New()
// 需要加密的字符串为
h.Write([]byte(src))
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}

func main() {
_sha1 := Sha1("始識")
_sha256 := SHA256("始識")
_sha512 := SHA512("始識")
fmt.Println(_sha1)
fmt.Println(_sha256)
fmt.Println(_sha512)
}

结果

7bac01cc58a26f3cb280b0466794a89441279946

6ef99e6d3fe34a46afcdc438435728fe95ffdab18e389ddd31609edd6729b11d

0c04e9b79f488646d0eac6f65468248507939d643cc92709b14eb0d18d8f13db509ed5ccd3312d6c234408185a4611a42525dce9e8d32255640f56a2f836635a

base 加密 解密

加密

1
2
3
4
5
// BASE64StdEncode base编码
func BASE64StdEncode(src string) string {
return base64.StdEncoding.EncodeToString([]byte(src))
}

解密

1
2
3
4
5
6
7
8
// BASE64StdDecode base解码
func BASE64StdDecode(src string) string {
a, err := base64.StdEncoding.DecodeString(src)
if err != nil {
_ = fmt.Errorf("解密失败,%v\n", err)
}
return string(a)
}

base64 调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import (
"encoding/base64"
"fmt"
)

// BASE64StdEncode base编码
func BASE64StdEncode(src string) string {
return base64.StdEncoding.EncodeToString([]byte(src))
}

// BASE64StdDecode base解码
func BASE64StdDecode(src string) string {
a, err := base64.StdEncoding.DecodeString(src)
if err != nil {
_ = fmt.Errorf("解密失败,%v\n", err)
}
return string(a)
}

func main() {
encodeBase64 := BASE64StdEncode("hybpjx")
decodeBase64 := BASE64StdDecode(encodeBase64)
fmt.Println(encodeBase64)
fmt.Println(decodeBase64)
}

结果

aHlicGp4
hybpjx

AES 加密

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
image.png
由于加密和解密的秘钥是相同的,所以AES为对称加密

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

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

func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}

func PKCS7UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}

//AES加密
func AesEncrypt(origData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
origData = PKCS7Padding(origData, blockSize)
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
crypted := make([]byte, len(origData))
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}

//AES解密
func AesDecrypt(crypted, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
origData := make([]byte, len(crypted))
blockMode.CryptBlocks(origData, crypted)
origData = PKCS7UnPadding(origData)
return origData, nil
}

func main() {
text := "今晚打老虎"
AesKey := []byte("0f90023fc9ae101e") //秘钥长度为16的倍数
fmt.Printf("明文: %s\n秘钥: %s\n", text, string(AesKey))
encrypted, err := AesEncrypt([]byte(text), AesKey)
if err != nil {
panic(err)
}
fmt.Printf("加密后: %s\n", base64.StdEncoding.EncodeToString(encrypted))
origin, err := AesDecrypt(encrypted, AesKey)
if err != nil {
panic(err)
}
fmt.Printf("解密后明文: %s\n", string(origin))
}


CBC方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package main

import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/hex"
"log"
)

func AesEncryptCBC(origData []byte, key []byte) (encrypted []byte) {
// 分组秘钥
// NewCipher该函数限制了输入k的长度必须为16, 24或者32
block, _ := aes.NewCipher(key)
blockSize := block.BlockSize() // 获取秘钥块的长度
origData = pkcs5Padding(origData, blockSize) // 补全码
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 加密模式
encrypted = make([]byte, len(origData)) // 创建数组
blockMode.CryptBlocks(encrypted, origData) // 加密
return encrypted
}
func AesDecryptCBC(encrypted []byte, key []byte) (decrypted []byte) {
block, _ := aes.NewCipher(key) // 分组秘钥
blockSize := block.BlockSize() // 获取秘钥块的长度
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // 加密模式
decrypted = make([]byte, len(encrypted)) // 创建数组
blockMode.CryptBlocks(decrypted, encrypted) // 解密
decrypted = pkcs5UnPadding(decrypted) // 去除补全码
return decrypted
}
func pkcs5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func pkcs5UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
func main() {
origData := []byte("460154561234") // 待加密的数据
key := []byte("9876787656785679") // 加密的密钥
log.Println("原文:", string(origData))

log.Println("------------------ CBC模式 --------------------")
encrypted := AesEncryptCBC(origData, key)
log.Println("密文(hex):", hex.EncodeToString(encrypted))
log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))
decrypted := AesDecryptCBC(encrypted, key)
log.Println("解密结果:", string(decrypted))
}

ECB方式

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

import (
"crypto/aes"
"encoding/base64"
"encoding/hex"
"log"
)


func AesEncryptECB(origData []byte, key []byte) (encrypted []byte) {
cipher, _ := aes.NewCipher(generateKey(key))
length := (len(origData) + aes.BlockSize) / aes.BlockSize
plain := make([]byte, length*aes.BlockSize)
copy(plain, origData)
pad := byte(len(plain) - len(origData))
for i := len(origData); i < len(plain); i++ {
plain[i] = pad
}
encrypted = make([]byte, len(plain))
// 分组分块加密
for bs, be := 0, cipher.BlockSize(); bs <= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
}

return encrypted
}
func AesDecryptECB(encrypted []byte, key []byte) (decrypted []byte) {
cipher, _ := aes.NewCipher(generateKey(key))
decrypted = make([]byte, len(encrypted))
//
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
}

trim := 0
if len(decrypted) > 0 {
trim = len(decrypted) - int(decrypted[len(decrypted)-1])
}

return decrypted[:trim]
}
func generateKey(key []byte) (genKey []byte) {
genKey = make([]byte, 16)
copy(genKey, key)
for i := 16; i < len(key); {
for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
genKey[j] ^= key[i]
}
}
return genKey
}

func main() {
origData := []byte("460154561234") // 待加密的数据
key := []byte("9876787656785679") // 加密的密钥
log.Println("原文:", string(origData))

log.Println("------------------ ECB模式 --------------------")
encrypted := AesEncryptECB(origData, key)
log.Println("密文(hex):", hex.EncodeToString(encrypted))
log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))
decrypted := AesDecryptECB(encrypted, key)
log.Println("解密结果:", string(decrypted))
}

CFB 方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package main

import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"encoding/hex"
"io"
"log"
)

func AesEncryptCFB(origData []byte, key []byte) (encrypted []byte) {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
encrypted = make([]byte, aes.BlockSize+len(origData))
iv := encrypted[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(encrypted[aes.BlockSize:], origData)
return encrypted
}
func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte) {
block, _ := aes.NewCipher(key)
if len(encrypted) < aes.BlockSize {
panic("ciphertext too short")
}
iv := encrypted[:aes.BlockSize]
encrypted = encrypted[aes.BlockSize:]

stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(encrypted, encrypted)
return encrypted
}
func main() {
origData := []byte("460154561234") // 待加密的数据
key := []byte("9876787656785679") // 加密的密钥
log.Println("原文:", string(origData))

log.Println("------------------ CFB模式 --------------------")
encrypted := AesEncryptCFB(origData, key)
log.Println("密文(hex):", hex.EncodeToString(encrypted))
log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))
decrypted := AesDecryptCFB(encrypted, key)
log.Println("解密结果:", string(decrypted))
}

RSA加密

RSA是一种基于公钥密码体制的优秀加密算法,1978年由美国(MIT)的李维斯特(Rivest)、沙米尔(Shamir)、艾德曼(Adleman)提的。
RSA算法是一种分组密码体制算法,它的保密强度是建立在具有大素数因子的合数其因子分解是困难的(基于大数分解的难度)。
公钥和私钥是一对大素数的函数,从一个公钥和密文中恢复出明文的难度等价于分解两个大素数之积。
RSA得到了世界上的最广泛的应用,ISO在1992年颁布的国际标准X.509中,将RSA算法正式纳入国际标准。

RSA加密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
)




// GenerateRSAKey 生成RSA私钥和公钥,保存到文件中
func GenerateRSAKey(bits int){
//GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
//Reader是一个全局、共享的密码用强随机数生成器
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err!=nil{
panic(err)
}
//保存私钥
//通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
// X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey) // PKCS1 和 9 是不一致的
X509PrivateKey,err := x509.MarshalPKCS8PrivateKey(privateKey)
if err != nil {
fmt.Println(err.Error())
os.Exit(0)
}
//使用pem格式对x509输出的内容进行编码
//创建文件保存私钥
privateFile, err := os.Create("private.pem")
if err!=nil{
panic(err)
}
defer privateFile.Close()
//构建一个pem.Block结构体对象
privateBlock:= pem.Block{Type: "PRIVATE KEY",Bytes:X509PrivateKey}
//将数据保存到文件
pem.Encode(privateFile,&privateBlock)
//保存公钥
//获取公钥的数据
publicKey:=privateKey.PublicKey
//X509对公钥编码
X509PublicKey,err:=x509.MarshalPKIXPublicKey(&publicKey)
if err!=nil{
panic(err)
}
//pem格式编码
//创建用于保存公钥的文件
publicFile, err := os.Create("public.pem")
if err!=nil{
panic(err)
}
defer publicFile.Close()
//创建一个pem.Block结构体对象
publicBlock:= pem.Block{Type: "Public Key",Bytes:X509PublicKey}
//保存到文件
pem.Encode(publicFile,&publicBlock)
}

// RsaEncrypt RSA加密
func RsaEncrypt(plainText []byte,path string)[]byte{
//打开文件
file,err:=os.Open(path)
if err!=nil{
panic(err)
}
defer file.Close()
//读取文件的内容
info, _ := file.Stat()
buf:=make([]byte,info.Size())
file.Read(buf)
//pem解码
block, _ := pem.Decode(buf)
//x509解码
publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err!=nil{
panic(err)
}
//类型断言
publicKey:=publicKeyInterface.(*rsa.PublicKey)
//对明文进行加密
cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
if err!=nil{
panic(err)
}
//返回密文
return cipherText
}

// RsaDecrypt RSA解密
func RsaDecrypt(cipherText []byte,path string) []byte{
//打开文件
file,err:=os.Open(path)
if err!=nil{
panic(err)
}
defer file.Close()
//获取文件内容
info, _ := file.Stat()
buf:=make([]byte,info.Size())
file.Read(buf)
//pem解码
block, _ := pem.Decode(buf)
//X509解码
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err!=nil{
fmt.Println(err.Error())
os.Exit(0)
}
//对密文进行解密
plainText,_:=rsa.DecryptPKCS1v15(rand.Reader,privateKey.(*rsa.PrivateKey),cipherText)
//返回明文
return plainText
}


func main(){
// RSA/ECB/PKCS1Padding
// RSA是算法,ECB是分块模式,PKCS1Padding是填充模式

// pkcs1私钥生成openssl genrsa -out pkcs1.pem 1024
// pkcs1转pkcs8私钥 :openssl pkcs8 -in pkcs8.pem -nocrypt -out pkcs1.pem

// pkcs1 BEGIN RSA PRIVATE KEY
// pkcs8 BEGIN PRIVATE KEY

GenerateRSAKey(1024)
publicPath := "public_key.pem"
privatePath := "private_key.pem"

publicPath = "public.pem"
privatePath = "private.pem"

txt := []byte("hello")
encrptTxt := RsaEncrypt(txt,publicPath)
decrptCode := RsaDecrypt(encrptTxt,privatePath)
fmt.Println(string(decrptCode))

}

RSA分段加密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package main

import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"log"
"os"
)

func main() {
GenerateRSAKey(2048)
publicPath := "public.pem"
privatePath := "private.pem"
var a = []byte("hello")
encrptTxt, err := RsaEncryptBlock(a, publicPath)
if err != nil {
fmt.Println(err.Error())
}
encodeString := base64.StdEncoding.EncodeToString(encrptTxt)
decodeByte, err := base64.StdEncoding.DecodeString(encodeString)
if err != nil {
panic(err)
}
//生成RSA私钥和公钥,保存到文件中
decrptCode := RSA_Decrypts(decodeByte, privatePath)
fmt.Println(string(decrptCode))

}


func GenerateRSAKey(bits int) {
//GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
//Reader是一个全局、共享的密码用强随机数生成器
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
panic(err)
}
//保存私钥
//通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
// X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey) // PKCS1 和 9 是不一致的
X509PrivateKey, err := x509.MarshalPKCS8PrivateKey(privateKey)
if err != nil {
fmt.Println(err.Error())
os.Exit(0)
}
//使用pem格式对x509输出的内容进行编码
//创建文件保存私钥
privateFile, err := os.Create("private.pem")
if err != nil {
panic(err)
}
defer privateFile.Close()
//构建一个pem.Block结构体对象
privateBlock := pem.Block{Type: "PRIVATE KEY", Bytes: X509PrivateKey}
//将数据保存到文件
pem.Encode(privateFile, &privateBlock)
//保存公钥
//获取公钥的数据
publicKey := privateKey.PublicKey
//X509对公钥编码
X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
if err != nil {
panic(err)
}
//pem格式编码
//创建用于保存公钥的文件
publicFile, err := os.Create("public.pem")
if err != nil {
panic(err)
}
defer publicFile.Close()
//创建一个pem.Block结构体对象
publicBlock := pem.Block{Type: "Public Key", Bytes: X509PublicKey}
//保存到文件
pem.Encode(publicFile, &publicBlock)
}

// RSA_Decrypts RSA解密支持分段解密
func RSA_Decrypts(cipherText []byte, path string) []byte {
//打开文件
var bytesDecrypt []byte
file, err := os.Open(path)
if err != nil {
panic(err)
}
defer file.Close()
//获取文件内容
info, _ := file.Stat()
buf := make([]byte, info.Size())
file.Read(buf)
//pem解码
block, _ := pem.Decode(buf)
//X509解码
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
fmt.Println(err.Error())
os.Exit(0)
}
p := privateKey.(*rsa.PrivateKey)
keySize := p.Size()
srcSize := len(cipherText)
log.Println("密钥长度", keySize, "密文长度", srcSize)
var offSet = 0
var buffer = bytes.Buffer{}
for offSet < srcSize {
endIndex := offSet + keySize
if endIndex > srcSize {
endIndex = srcSize
}
bytesOnce, err := rsa.DecryptPKCS1v15(rand.Reader, p, cipherText[offSet:endIndex])
if err != nil {
return nil
}
buffer.Write(bytesOnce)
offSet = endIndex
}
bytesDecrypt = buffer.Bytes()
return bytesDecrypt
}

// RsaEncryptBlock 公钥加密-分段
func RsaEncryptBlock(src []byte, path string) (bytesEncrypt []byte, err error) {
//打开文件
file, err := os.Open(path)
if err != nil {
panic(err)
}
defer file.Close()
//读取文件的内容
info, _ := file.Stat()
buf := make([]byte, info.Size())
file.Read(buf)
//pem解码
block, _ := pem.Decode(buf)
//x509解码
publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
panic(err)
}
//类型断言
publicKey := publicKeyInterface.(*rsa.PublicKey)
keySize, srcSize := publicKey.Size(), len(src)
log.Println("密钥长度", keySize, "明文长度", srcSize)
offSet, once := 0, keySize-11
buffer := bytes.Buffer{}
for offSet < srcSize {
endIndex := offSet + once
if endIndex > srcSize {
endIndex = srcSize
}
// 加密一部分
bytesOnce, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, src[offSet:endIndex])
if err != nil {
return nil, err
}
buffer.Write(bytesOnce)
offSet = endIndex
}
bytesEncrypt = buffer.Bytes()
return
}

DES加密

  • DES(Data Encryption)是1977年美国联邦信息处理标准(FIPS)中所采用的一种对称密码(FIPS46-3),一直以来被美国及其他国家的政府和银行等广泛使用。随着计算机的进步,DES已经能够被暴力破解,1997年的DES Challenge I 中用了96天破译密钥,1998年的DES Challenge II-1中用了41天,1998年的DES Challenge II-2中用了56小时,1999年的DES Challenge III 中只用了22小时15分钟。
  • DES是一种将64比特的明文加密成64比特的密文的对称密码算法,它的密钥的长度是56比特。尽管从规格上来说,DES的密钥长度是64比特,但由于每隔7比特会设置一个用于错误检查的比特,因此实质上其密钥长度是56比特。
  • DES 是以64比特的明文(比特序列)为一个单位来进行加密的,这个64比特的单位称为分组 ,一般来说,以分组为单位进行处理的密码算法称为分组密码,DES就是分组密码的一种。
  • DES每次只能加密64比特的数据,如果要加密的明文比较长,就需要对DES加密进行迭代(反复),而迭代的具体方式就称为模式。
  • DES 内部实现理论:在 des 中各个步骤称为轮,整个加密过程进行16轮循环。

内置库完成

加密模式采用ECB、填充方式采用pkcs5padding、密码使用”12345678”,输出时经hex编码。自己可以通过一些在线测试工具进行测试,看结果是否一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package main

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

func main() {
data := []byte("hello world")
key := []byte("12345678")
iv := []byte("43218765")

result, err := DesCBCEncrypt(data, key, iv)
if err != nil {
fmt.Println(err)
}
b := hex.EncodeToString(result)
fmt.Println(b)
}

func DesCBCEncrypt(data, key, iv []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}

data = pkcs5Padding(data, block.BlockSize())
cryptText := make([]byte, len(data))

blockMode := cipher.NewCBCEncrypter(block, iv)
blockMode.CryptBlocks(cryptText, data)
return cryptText, nil
}

func pkcs5Padding(cipherText []byte, blockSize int) []byte {
padding := blockSize - len(cipherText)%blockSize
padText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(cipherText, padText...)
}

使用第三方库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"fmt"
"github.com/marspere/goencrypt"
)

func main() {
// key为12345678
// iv为空
// 采用ECB分组模式
// 采用pkcs5padding填充模式
// 输出结果使用base64进行加密
cipher := goencrypt.NewDESCipher([]byte("12345678"), []byte(""), goencrypt.ECBMode, goencrypt.Pkcs7, goencrypt.PrintBase64)
cipherText, err := cipher.DESEncrypt([]byte("hello world"))
if err != nil {
fmt.Println(err)
return
}
fmt.Println(cipherText)
}

3DES加密算法

3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。
由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
还有一个库 非常NB

ECB模式下的3DES算法加解密信息,golang默认只提供CBC模式
这边有golang的加密库,非常厉害
github.com/forgoer/openssl

安装:
go get github.com/thinkoner/openssl

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import (
"encoding/base64"
"encoding/hex"
"fmt"
"github.com/forgoer/openssl"
)

func main() {

//定义密钥,必须是24byte
key := []byte("123456789012345678901234")
fmt.Println("密钥:", key, hex.EncodeToString(key))

//定义明文
src := []byte("0102030109000000030000000F8898E37A7F8F3D742006111118080000FACE05")

//3DES-ECB加密
encodeData, _ := openssl.Des3ECBEncrypt(src, key, openssl.ZEROS_PADDING)
encryptBaseData := base64.StdEncoding.EncodeToString(encodeData)

fmt.Println("加密后Base64:", encryptBaseData)
fmt.Println("加密后Hex:", hex.EncodeToString(encodeData))

//3DES-ECB解密
decodeBaseData, _ := base64.StdEncoding.DecodeString(encryptBaseData)
decodeData, _ := openssl.Des3ECBDecrypt(decodeBaseData, key, openssl.ZEROS_PADDING)

fmt.Println("解密后:", hex.EncodeToString(decodeData))
}

包括 Des的加密解密

以下只举一个例子

1
2
3
4
5
6
srcData := "L0j+JvbeVM0svSpjIwXdE7yTu78wiEszCmW8rwjXY3vrx2nEaUeJ/Rw/c/IRdlxIH+/ro4pykx6ESOkGU1YwM8ddEuuoTg5uPsqQ9/SuNds="
key := []byte("Ctpsp@884*"[:8])
//3DES-ECB解密
decodeBaseData, _ := base64.StdEncoding.DecodeString(srcData)
decodeData, _ := openssl.DesECBDecrypt(decodeBaseData, key, openssl.PKCS5_PADDING)
fmt.Println("解密后:", string(decodeData))
  • 标题: Golang加密解密算法
  • 作者: 流转
  • 创建于 : 2022-09-26 17:06:57
  • 更新于 : 2024-10-23 12:45:17
  • 链接: http://hybpjx.github.io/2022/09/26/Golang加密解密算法/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论