首页 > golang > 【Golang】✔️实战✔️ 10 种加密方法实现 ☢️万字长文 建议手收藏☢️
2019
07-30

【Golang】✔️实战✔️ 10 种加密方法实现 ☢️万字长文 建议手收藏☢️



【Golang】✔️实战✔️ 10 种加密方法实现 ☢️万字长文 建议手收藏☢️


概述

今天来带大家实现以下最常用的 10 中加密方法. 建议收藏!

【Golang】✔️实战✔️ 10 种加密方法实现 ☢️万字长文 建议手收藏☢️_原力计划

md5

md5 (Message-Digest Algorithm 5) 是凸一套验证系统, 对输入会生成一个 128 位的散列值 (hash value)

【Golang】✔️实战✔️ 10 种加密方法实现 ☢️万字长文 建议手收藏☢️_字符串_02

例子:

package main
import (
"crypto/md5"
"fmt"
)
func main() {

// 定义字符串
var str = "Hello World"
fmt.Println("待加密文本:", str)
// 实例化md5
my_md5 := md5.New()
// 写入待加密内容
my_md5.Write([]byte(str))
// 计算md5
result := my_md5.Sum(nil)
// 以字节的形式输出
fmt.Println(result)
// 以字符串的形式输出
fmt.Printf("md5 值: %x", result)
}

输出结果:

待加密文本: Hello World
[177 10 141 177 100 224 117 65 5 183 169 155 231 46 63 229]
md5 值: b10a8db164e0754105b7a99be72e3fe5

SHA-2

安全散列验算 SHA (Secure Hash Algorithm) 是一个密码散列函数家族. 今天我们主要讲解 SHA-2 里面的 sha256 和 sha512.

sha256

sha256 对于任意长度的消息, 都会产生一个 256 bit 的哈希值, 也就是信息摘要.

例子:

package main
import (
"crypto/sha256"
"fmt"
)
func main() {
// 定义变量
var str = "Hello World"
// 实例化sha256
my_sha256 := sha256.New()
// 写入
my_sha256.Write([]byte(str))
// 计算哈希
result := my_sha256.Sum(nil)
// 以字节的形式输出
fmt.Println(result)
// 以字符串的形式输出
fmt.Printf("sha256 值: %x", result)
}

输出结果:

[165 145 166 212 11 244 32 64 74 1 23 51 207 183 177 144 214 44 101 191 11 205 163 43 87 178 119 217 173 159 20 110]
sha256 值: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e

sha512

sha512 对于任意长度的消息, 都会产生一个 256 bit 的哈希值, 也就是信息摘要.

例子:

package main
import (
"crypto/sha512"
"fmt"
)
func main() {
// 定义变量
var str = "Hello World"
// 实例化sha512
my_sha512 := sha512.New()
// 写入
my_sha512.Write([]byte(str))
// 计算哈希
result := my_sha512.Sum(nil)
// 以字节的形式输出
fmt.Println(result)
// 以字符串的形式输出
fmt.Printf("sha512 值: %x", result)
}

输出结果:

[44 116 253 23 237 175 216 14 132 71 176 212 103 65 238 36 59 126 183 77 210 20 154 10 177 185 36 111 179 3 130 242 126 133 61 133 133 113 158 14 103 203 218 13 170 143 81 103 16 100 97 93 100 90 226 122 203 21 191 177 68 127 69 155]
sha512 值: 2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b

计算文件哈希

package main
import (
"crypto/sha256"
"fmt"
"io"
"os"
)
func hash_sha256_file(filepath string)(string, error) {
// 返回哈希字符串
var hash_value string
// 打开文件
file, err := os.Open(filepath)
if err != nil {
// 文件打开错误返回空哈希
return hash_value, err
}
// 延时
defer file.Close()
// 实例化
my_hash := sha256.New()
// 拷贝文件
_, err = io.Copy(my_hash, file)
if err != nil {
return hash_value, err
}
// 计算哈希
hash_byte := my_hash.Sum(nil)
// 转换成字符串
hash_value = fmt.Sprintf("%x", hash_byte)
return hash_value, nil
}
func main() {
// 文件路径
file_path := "crypto/file_hash/1.txt"
// 计算hash
hash, err := hash_sha256_file(file_path)
if err != nil {
panic(err.Error())
}
// 调试输出
fmt.Printf("%s sha256 is:n%s", file_path, hash)
}

输出结果:

crypto/file_hash/1.txt sha256 is:
b53748fd51fe014aebbf9a8d1cbcd137a6da5b8c808d34a8509fc7d5d1017a0b

base64

base64 是一种任意二进制到文本字符串的编码方式.

例子:

package main
import (
"encoding/base64"
"fmt"
)
func main() {
// 定义字符串
str := "Hello World"
// base64加密
encode := base64.StdEncoding.EncodeToString([]byte(str))
// base64解密
decode, err := base64.StdEncoding.DecodeString(encode)
if err != nil {
panic(err)
}
// 输出结果
result := fmt.Sprintf("%s", decode)
fmt.Println(result)
}

输出结果:

Hello World

AES

AES (Advance Encryption Standard) 是一种堆成加密算法. AES 会把文件切分成 128 位的小块进行加密.

AES 的三个部分:


  • 密钥: AES 算法加密和解密使用的是同一个密钥, 密钥分为三个长度: 128 位, 192 位, 256 位
  • 填充: AES 算法会对明文按照 128 bit 一块来进行拆分, 如果明文块不满 128 bit 就会进行填充
  • 模式: ASE 加密算法提供了 5 种不同的工作模式: ECB, CBC, CTR, CFB, OFB

【Golang】✔️实战✔️ 10 种加密方法实现 ☢️万字长文 建议手收藏☢️_golang_03

例子:

package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
)
// 全零填充
func zero_padding(text []byte, block_size int) []byte {
// 计算最后一个区块的长度
last_block := len(text) % block_size
// 计算填充长度
padding_len := block_size - last_block
// 全零填充
padding := bytes.Repeat([]byte{0}, padding_len)
result := append(text, padding...)
return result
}
// 去除填充
func un_padding(encode_text []byte) []byte {
// 去除尾部的0
un_pad := bytes.TrimRightFunc(encode_text, func(r rune)bool{
return r == rune(0)
})
return un_pad
}
// AES加密
func AES_encrypt(text, key []byte)([]byte, error) {
// 创建密码, 根据密码加密
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// 定义大小 (16byte=128bit)
block_size := block.BlockSize()
// 定义偏移量
iv := key[:block_size]
// 填充
text_padded := zero_padding(text, block_size)
// 创建加密算法
block_mode := cipher.NewCBCEncrypter(block, iv)
// 创建空间
encrypt := make([]byte, len(text_padded))
// 加密
block_mode.CryptBlocks(encrypt, text_padded)
return encrypt, nil
}
// AES解密
func AES_decrypt(text, key []byte)([]byte, error) {
// 创建密码, 根据密码解密
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// 定义大小 (16byte=128bit)
block_size := block.BlockSize()
// 定义偏移量
iv := key[:block_size]
// 创建加密算法
block_mode := cipher.NewCBCDecrypter(block, iv)
// 创建空间
decrypt := make([]byte, len(text))
// 解密
block_mode.CryptBlocks(decrypt, text)
// 去除填充
result := un_padding(decrypt)
return result, nil
}
func main() {
// 定义待加密文本
str := "Hello World"
// 定义密码(16, 24, 32)
key := []byte("我是小白呀!")
fmt.Println("原文本:", str, "密码:", string(key))
// 加密
encrypted, err := AES_encrypt([]byte(str), key)
if err != nil {
panic(err)
}
fmt.Println("加密结果:", base64.StdEncoding.EncodeToString(encrypted))
// 解密
decrypted, err := AES_decrypt(encrypted, key)
if err != nil {
panic(err)
}
fmt.Println("解密结果:", string(decrypted))
}

输出结果:

原文本: Hello World 密码: 我是小白呀!
加密结果: E38HbHZVeXozFDHoHrSh6Q==
解密结果: Hello World

DES

DES (Data Encryption Standard) 即数据加密标准. 是一种使用密钥的对称加密算法.

【Golang】✔️实战✔️ 10 种加密方法实现 ☢️万字长文 建议手收藏☢️_区块链_04

DES

例子:

package main
import (
"bytes"
"crypto/cipher"
"crypto/des"
"encoding/base64"
"fmt"
)
// 全零填充
func zero_padding(text []byte, block_size int) []byte {
// 计算最后一个区块的长度
last_block := len(text) % block_size
// 计算填充长度
padding_len := block_size - last_block
// 全零填充
padding := bytes.Repeat([]byte{0}, padding_len)
result := append(text, padding...)
return result
}
// 去除填充
func un_padding(encode_text []byte) []byte {
// 去除尾部的0
un_pad := bytes.TrimRightFunc(encode_text, func(r rune)bool{
return r == rune(0)
})
return un_pad
}
func DES_encrypt(text, key []byte) ([]byte, error) {
// 创建密码, 根据密码加密
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
// 区块大小
block_size := block.BlockSize()
// 偏移量
iv := key[:block_size]
// 填充
text_padded := zero_padding(text, block_size)
// 创建加密算法
block_mode := cipher.NewCBCEncrypter(block, iv)
// 创建空间
encryped := make([]byte, len(text_padded))
// 加密
block_mode.CryptBlocks(encryped, text_padded)
return encryped, nil
}
func DES_decrypt(text, key []byte) ([]byte, error) {
// 创建密码, 根据密码解密
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
// 区块大小
block_size := block.BlockSize()
// 偏移量
iv := key[:block_size]
// 创建加密算法
block_mode := cipher.NewCBCDecrypter(block, iv)
// 创建空间
decryped := make([]byte, len(text))
// 加密
block_mode.CryptBlocks(decryped, text)
// 去除填充
result := un_padding(decryped)
return result, nil
}
func main() {
// 定义待加密文本
str := "Hello World"
// 定义密码
key := []byte("12345678")
fmt.Println("原文本:", str, "密码:", string(key))
// 加密
encrypted, err := DES_encrypt([]byte(str), key)
if err != nil {
panic(err)
}
fmt.Println("加密结果:", base64.StdEncoding.EncodeToString(encrypted))
// 解密
decrypted, err := DES_decrypt(encrypted, key)
if err != nil {
panic(err)
}
fmt.Println("解密结果:", string(decrypted))
}

输出结果:

原文本: Hello World 密码: 12345678
加密结果: w3VRu3f3QdC83BZJe0+XsQ==
解密结果: Hello World

3DES

3DES 在 DES 的基础上进行 三次加密.

【Golang】✔️实战✔️ 10 种加密方法实现 ☢️万字长文 建议手收藏☢️_golang_05

3DES 的加密过程:

  • C=Ek3(Dk2(Ek1§))

3DES 的解密过程:

  • P=Dk1((EK2(Dk3©))

例子:

package main
import (
"bytes"
"crypto/cipher"
"crypto/des"
"encoding/base64"
"fmt"
)
// 全零填充
func zero_padding(text []byte, block_size int) []byte {
// 计算最后一个区块的长度
last_block := len(text) % block_size
// 计算填充长度
padding_len := block_size - last_block
// 全零填充
padding := bytes.Repeat([]byte{0}, padding_len)
result := append(text, padding...)
return result
}
// 去除填充
func un_padding(encode_text []byte) []byte {
// 去除尾部的0
un_pad := bytes.TrimRightFunc(encode_text, func(r rune) bool {
return r == rune(0)
})
return un_pad
}
func three_DES_encrypt(text, key []byte) ([]byte, error) {
// 创建密码, 根据密码加密
block, err := des.NewTripleDESCipher(key)
if err != nil {
return nil, err
}
// 区块大小
block_size := block.BlockSize()
// 偏移量
iv := key[:block_size]
// 填充
text_padded := zero_padding(text, block_size)
// 创建加密算法
block_mode := cipher.NewCBCEncrypter(block, iv)
// 创建空间
encryped := make([]byte, len(text_padded))
// 加密
block_mode.CryptBlocks(encryped, text_padded)
return encryped, nil
}
func three_DES_decrypt(text, key []byte) ([]byte, error) {
// 创建密码, 根据密码解密
block, err := des.NewTripleDESCipher(key)
if err != nil {
return nil, err
}
// 区块大小
block_size := block.BlockSize()
// 偏移量
iv := key[:block_size]
// 创建加密算法
block_mode := cipher.NewCBCDecrypter(block, iv)
// 创建空间
decryped := make([]byte, len(text))
// 加密
block_mode.CryptBlocks(decryped, text)
// 去除填充
result := un_padding(decryped)
return result, nil
}
func main() {
// 定义待加密文本
str := "Hello World"
// 定义密码
key := []byte("123456788765432111223344")
fmt.Println("原文本:", str, "密码:", string(key))
// 加密
encrypted, err := three_DES_encrypt([]byte(str), key)
if err != nil {
panic(err)
}
fmt.Println("加密结果:", base64.StdEncoding.EncodeToString(encrypted))
// 解密
decrypted, err := three_DES_decrypt(encrypted, key)
if err != nil {
panic(err)
}
fmt.Println("解密结果:", string(decrypted))
}

输出结果:

原文本: Hello World 密码: 123456788765432111223344
加密结果: jxJvRrF0zCpQP6KJbpsQyQ==
解密结果: Hello World

我们可以看到 3DES 的密码是 DES 的三倍, 为 64 * 3 位, 分别对应 key1, key2, key3.

RSA

RSA 加密是一种非对称, 公开密钥的加密算法. 在 1977 年由 罗纳德.李维斯特 (Ron Rivest), 阿迪.萨莫尔 (Adi Shamir) 和伦纳德.阿德曼 (Leonard Adleman) 一起提出, 这也是 “RSA” 这个名字的由来.

【Golang】✔️实战✔️ 10 种加密方法实现 ☢️万字长文 建议手收藏☢️_区块链_06

RSA 的组成部分:


  1. 原文 (M: message): 需要加密的内容
  2. 密文 (C: ciphertext): 加密后得到的信息
  3. 公钥 (PU: public key) & 私钥 (PR: private key)
  4. 加密算法 (E: encryption): C = E(M) 即为加密过程
  5. 解密算法 (D: decryption): M = D© 即为解密过程

RSA 的流程:

  • 简单的来说就是计算两个质数的乘积容易, 但是用乘积反推两个质数难. 具体的过程推荐大家看李永乐老师的视频

函数详解

GenerateKey()

GenerateKey 函数使用随机数生成器, 生成一对具有指定字位数的 RSA 密钥.

格式:

rsa.GenerateKey(random io.Reader, bits int)
  • bits: 生成密钥的位数

MarshalPKCS1PrivateKey()

使用 x509 标准将 rsa 私钥序列转化为 PKCS #1, ANS.1 的 DER 编码.

格式:

x509.MarshalPKCS1PrivateKey(key *rsa.PrivateKey)

pem 编码

格式:

pem.Encode(out io.Writer, b *Block)

  • out: 输出文件
  • block: 区块

生成公钥私钥

package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"flag"
"fmt"
"os"
)
func GenRsaKey(bits int) error {
// 生成私钥
private_key, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
fmt.Println("私钥生成失败")
}
fmt.Println(private_key)
// 处理private key
derStream := x509.MarshalPKCS1PrivateKey(private_key)
// 按照块处理
block := &pem.Block{
Type: "PRIVATE KEY",
Bytes: derStream,
}
// 创建文件存储私钥
private_key_file, err := os.Create("RSA/RSA_generate_key/rsa_private_key.pem")
if err != nil {
return err
}
// 延时关闭
defer private_key_file.Close()
// 进行pem编码, 写入文件
err = pem.Encode(private_key_file, block)
if err != nil {
return err
}
// 生成公钥
public_key := &private_key.PublicKey
fmt.Println(public_key)
// 处理公钥
derpkix, err := x509.MarshalPKIXPublicKey(public_key)
if err != nil {
return err
}
// 按照块处理
block = &pem.Block{
Type: "PUBLIC KEY",
Bytes: derpkix,
}
// 创建文件存储公钥
public_key_file, err := os.Create("RSA/RSA_generate_key/rsa_public_key.pem")
if err != nil {
return err
}
// 延时关闭
defer public_key_file.Close()
// 进行pem编码, 写入文件
err = pem.Encode(public_key_file, block)
if err != nil {
return err
}
return nil
}
func main() {
// 生成密钥
var bits int
flag.IntVar(&bits, "b", 1024, "密码长度默认1024")
// 生成私钥
err := GenRsaKey(bits)
if err != nil {
}
}

实现加密

package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"os"
)
var public_key = []byte("")
var private_key = []byte("")
func read_key() {
// 文件路径
public_key_path := "RSA/RSA_generate_key/rsa_public_key.pem"
private_key_path := "RSA/RSA_generate_key/rsa_private_key.pem"
// 打开文件
public, err := os.Open(public_key_path)
if err != nil {
panic(err)
}
private, err := os.Open(private_key_path)
if err != nil {
panic(err)
}
// 延时关闭
defer public.Close()
defer private.Close()
// 读取内容
public_key, err = ioutil.ReadAll(public)
if err != nil {
panic(err)
}
private_key, err = ioutil.ReadAll(private)
if err != nil {
panic(err)
}
}
func RSA_encrypt(text []byte) ([]byte, error) {
// pem解码
block, _ := pem.Decode(public_key)
if block == nil {
return nil, errors.New("私钥无效")
}
// 获取公钥
public_interface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
// 断言类型转换 (interface -> *rsa.PublicKey)
pub := public_interface.(*rsa.PublicKey)
// 加密
encode, err := rsa.EncryptPKCS1v15(rand.Reader, pub, text)
if err != nil {
return nil, err
}
return encode, nil
}
func RSA_decrypt(text []byte) ([]byte, error) {
// pem解码
block, _ := pem.Decode(private_key)
if block == nil {
return nil, errors.New("私钥无效")
}
// x509反序列化, 获取私钥
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
// 解密
decrypt, err := rsa.DecryptPKCS1v15(rand.Reader, priv, text)
return decrypt, err
}
func main() {
// 读取公钥私钥
read_key()
// 代加密文本
text := "我是小白呀"
// 加密
encrypted, err := RSA_encrypt([]byte(text))
if err != nil {
fmt.Println("Error:", err.Error())
}
// 调试输出
fmt.Println("加密:", base64.StdEncoding.EncodeToString(encrypted))
// 解密
result, err := RSA_decrypt(encrypted)
if err != nil {
fmt.Println("Error:", err.Error())
}
fmt.Println("解密:", string(result))
}

输出结果:

加密:
rm6qUMKiWpMmoqvv+7h0fx2nXuu4bcFV9cv6RKlVII9iMbdS5dYOAK5Y0vzl5n+ukmUYfeNDzUzmpacs2laGF/ETzSR3bYl4sa3dTtgDIxdUeMGwpl0f9j1S4C+Ic8UagmW+XBDR0SrTGHOhzb+0lK2LTl7XRJENOYkaSSW5mKk=
解密: 我是小白呀

【Golang】✔️实战✔️ 10 种加密方法实现 ☢️万字长文 建议手收藏☢️_golang_07



作者:golang中国
golang中国

本文》有 9972 条评论

留下一个回复