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

  • 概述
  • md5
  • SHA-2
    • sha256
    • sha512
    • 计算文件哈希
  • base64
  • AES
  • DES
    • DES
    • 3DES
  • RSA
    • 函数详解
      • GenerateKey()
      • MarshalPKCS1PrivateKey()
      • pem 编码
    • 生成公钥私钥
    • 实现加密

概述

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

md5

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

例子:

package mainimport ("crypto/md5""fmt"
)func main() {// 定义字符串var str = "Hello World"fmt.Println("待加密文本:", str)// 实例化md5my_md5 := md5.New()// 写入待加密内容my_md5.Write([]byte(str))// 计算md5result := 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 mainimport ("crypto/sha256""fmt"
)func main() {// 定义变量var str = "Hello World"// 实例化sha256my_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 mainimport ("crypto/sha512""fmt"
)func main() {// 定义变量var str = "Hello World"// 实例化sha512my_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 mainimport ("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"// 计算hashhash, 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 mainimport ("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

例子:

package mainimport ("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 {// 去除尾部的0un_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) 即数据加密标准. 是一种使用密钥的对称加密算法.

DES

例子:

package mainimport ("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 {// 去除尾部的0un_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 的基础上进行 三次加密.

3DES 的加密过程:

  • C=Ek3(Dk2(Ek1§))

3DES 的解密过程:

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

例子:

package mainimport ("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 {// 去除尾部的0un_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” 这个名字的由来.

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 mainimport ("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 keyderStream := 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.PublicKeyfmt.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 intflag.IntVar(&bits, "b", 1024, "密码长度默认1024")// 生成私钥err := GenRsaKey(bits)if err != nil {}}

实现加密

package mainimport ("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 种加密方法实现 ☢️万字长文 建议手收藏☢️相关推荐

  1. 这10种项目管理方法,PMP项目经理备考收藏

    文章目录 **1. 敏捷开发** **2. Scrum** **3.** **Dev****O****ps** **4.** **Scrumban** **5.** **项目管理的知识体系** **6 ...

  2. 弱加密算法有哪几种_常见的几种加密方法

    常见的几种加密方法和实 常见的几种加密方法 : MD5 SHA1 RSA AES DES 1.MD5加密 是HASH算法一种. 是生成32位的数字字母混合码. MD5主要特点是 不可逆 MD5算法还具 ...

  3. R语言生存分析COX回归分析实战:两种治疗方法发生肾功能损害的情况

    R语言生存分析COX回归分析实战:两种治疗方法发生肾功能损害的情况 目录

  4. 电脑无法启动故障的10种解决方法

    电脑无法启动故障的10种解决方法 开机自检时出现问题后会出现各种各样的英文短句,短句中包含了非常重要的信息,读懂这些信息可以自己解决一些小问题,可是这些英文难倒了一部分朋友,下面是一些常见的BIOS短 ...

  5. 计算机常用的四种加密方法,电脑常见的几种加密方法

    电脑常见的几种加密方法 加密可以用于保证安全性, 但是其它一些技术在保障通信安全方面仍然是必须的,尤其是关于数据完整性和信息验证;例如,信息验证码(MAC)或者数字签名.另一方面的考虑是为了应付流量分 ...

  6. win10系统没声音 服务器,win10电脑突然没有声音的10种修复方法

    win10电脑突然没有声音的10种修复方法 发布时间:2020-08-07 05:18:26 来源:ITPUB博客 阅读:140 作者:XINQUDAO 不少用户在面对win10电脑突然没有声音的问题 ...

  7. 前端常用的几种加密方法

    目前在前端开发中基本都会用到加密,最常见的就是登录密码的加密.接下来会为大家介绍几种加密方法. md5 加密 MD5 加密后的位数有两种:16 位与 32 位.默认使用32位. (16 位实际上是从 ...

  8. 保护光盘数据的八种加密方法

    保护光盘数据的八种加密方法 为了防止盗版软件对软件市场的侵害,越来越多的软件商使用加密方法来保护自己的软件.尽管目前加密光盘的方法有很多种,但其主要原理是利用特殊的光盘母盘上的某些特征信息是不可再现的 ...

  9. 下班之后的10种放松方法

    在经历了一天激烈的打拼后,不少职场中人会将工作场所的紧张情绪带回家中,回到家中仍然无法放松.如果发生这种情况,试试以下10种调节方法,它们能够帮助你从办公状态调整到居家状态: 1.将工作留在办公室 下 ...

  10. 【OpenCV】 ⚠️实战⚠️ 女子深夜久久不能入眠,300行写出全能扫描王! ☢️建议手收藏☢️

    [OpenCV] ⚠️实战⚠️ 女子深夜久久不能入眠,300行写出全能扫描王! ☢️建议手收藏☢️ 概述 图像透视 获取透视矩阵 透视变换 预处理 其他函数 主函数 输出结果 最终转换结果 概述 今天 ...

最新文章

  1. android gridview控件使用详解_作为Android 开发者该如何进阶?
  2. 快速成长为数据挖掘高手的秘诀
  3. P3235-[HNOI2014]江南乐【整除分块,SG函数】
  4. 修改安装路径 pip 以及修改运行路径
  5. (作者:无名`)svn提交代码到本地仓库
  6. Linux IPC实践(5) --System V消息队列(2)
  7. 我的小白同事接触白鹭引擎4天,成功做了一款足球小游戏
  8. wxpython bind自定义_wxpython 支持python语法高亮的自定义文本框控件的代码
  9. python web access_利用python分析access日志的方法
  10. 正解mysql: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /usr/lib64/libstdc++.so.6)
  11. java制作进度条_使用Java高速实现进度条
  12. 最受欢迎的9个前端UI框架
  13. 生活-痘痘告诉你,身体哪里生病了
  14. TP+UC+DZ同步登陆问题汇总
  15. java mongodb 查询 游标_MongoDB find()方法:查询数据
  16. 算法 - 多目标优化的注意点及常用方法概述
  17. 平克四部曲之《白板》
  18. linux是类unix操作系统
  19. JIL和移动Widget
  20. 2022中式烹调师(初级)特种作业证考试题库及答案

热门文章

  1. 物联网芯片+区块链底层融合:紫光展锐开创产业升级新思路
  2. 【北京-亚运村】这7家公司推荐给你
  3. Google Analytics SEO 实时 网站 访问量 统计
  4. 前后端报文传输加密方案
  5. icem密度盒怎么设置_ICEM学习笔记
  6. javaFx(7)文本阅读器
  7. 《黑白团团队》第八次团队作业:Alpha冲刺 第五天
  8. android按键录制,安卓按键精灵怎么录制脚本
  9. Java打造RPC框架(四):支持zookeeper与负载均衡
  10. 马可夫链和隐马可夫链_马可夫随机场和图像处理