主流加密方式

  • cipher
  • aes
  • des
  • md5
  • sha256
  • dsa
  • ecdsa
  • elliptic
  • hmac
  • rand
  • rc4
  • rsa

aes

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),对称加密

如美国联邦信息处理标准出版物197中所定义的,aes实现 AES 加密(以前称为 Rijndael)。
这个包中的 AES 操作不是使用恒定时间算法实现的。在支持 AES 的硬件支持的系统上运行时会有一个例外,这些操作会使这些操作保持恒定时间。例子包括使用 AES-NI 扩展的 amd64 系统和使用 Message-Security-Assist 扩展的 s390x 系统。在这样的系统中,当 NewCipher 的结果传递给 cipher.NewGCM 时,GCM 使用的 GHASH 操作也是恒定的

我们来演示一下加密解密过程

package main

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

func main() {
  testAes()
}

func testAes() {
  // AES-128。key长度:16, 24, 32 bytes 对应 AES-128, AES-192, AES-256
  key := []byte("1234560123456789")
  result, err := AesEncrypt([]byte("123"), key)
  if err != nil {
    panic(err)
  }
  fmt.Println(base64.StdEncoding.EncodeToString(result))
  origData, err := AesDecrypt(result, key)
  if err != nil {
    panic(err)
  }
  fmt.Println(string(origData))
}

// 加密
func AesEncrypt(origData, key []byte) ([]byte, error) {
  // 1.创建密文变量

  block, err := aes.NewCipher(key)
  if err != nil {
    return nil, err
  }
  // 2.获取块的大小
  blockSize := block.BlockSize()
  // 3.使用算法填充数据使其程度成为key的整数倍
  origData = PKCS5Padding(origData, blockSize)
  // origData = ZeroPadding(origData, block.BlockSize())

  // 4.创建加密类型变量
  blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])

  // 5.
  crypted := make([]byte, len(origData))
  // 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
  // crypted := origData

  // 6.开始加密
  blockMode.CryptBlocks(crypted, origData)
  return crypted, nil
}


// 解密
func AesDecrypt(crypted, key []byte) ([]byte, error) {
  // 1.创建密文变量
  block, err := aes.NewCipher(key)
  if err != nil {
    return nil, err
  }
  // 2.获取加密块长度
  blockSize := block.BlockSize()
  
  //3.创建解密数据
  blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
  
  // 4.创建解密后存放数据的变量
  origData := make([]byte, len(crypted))
  // origData := crypted
  
  // 5.解密数据
  blockMode.CryptBlocks(origData, crypted)
  
  // 6.去掉填充
  origData = PKCS5UnPadding(origData)
  // origData = ZeroUnPadding(origData)
  return origData, nil
}

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

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

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 次
  unpadding := int(origData[length-1])
  return origData[:(length - unpadding)]
}
image.png

上面演示把‘123’通过一个秘钥key加密和解密的过程1234560123456789

des

DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密

package main

import (
"bytes"
"crypto/cipher" //cipher密码
"crypto/des"
"encoding/base64" //将对象转换成字符串
"fmt"
)

/**
 * DES加密方法
 */
func MyDesEncrypt(orig, key string) string{

// 1.将加密内容和秘钥转成字节数组
origData := []byte(orig)
k := []byte(key)

// 2.创建一个加密器
block, _ := des.NewCipher(k)

//3.将明文按秘钥的长度做补全操作
origData = PKCS5Padding(origData, block.BlockSize())

//4.返回一个解密接口-CBC
blockMode := cipher.NewCBCEncrypter(block, k)

//5.创建明文长度的字节数组
crypted := make([]byte, len(origData))

// 6.加密明文
blockMode.CryptBlocks(crypted, origData)

//将字节数组转换成字符串,base64编码
return base64.StdEncoding.EncodeToString(crypted)

}

/**
 * DES解密方法
 */
func MyDESDecrypt(data string, key string) string {

k := []byte(key)

//将加密字符串用base64转换成字节数组
crypted, _ := base64.StdEncoding.DecodeString(data)

//将字节秘钥转换成block快
block, _ := des.NewCipher(k)

//设置解密方式-CBC
blockMode := cipher.NewCBCDecrypter(block, k)

//创建密文大小的数组变量
origData := make([]byte, len(crypted))

//解密密文到数组origData中
blockMode.CryptBlocks(origData, crypted)

//去掉加密时补全的部分
origData = PKCS5UnPadding(origData)

return string(origData)
}

/**
 * 实现明文的补全
 * 如果ciphertext的长度为blockSize的整数倍,则不需要补全
 * 否则差几个则被几个,例:差5个则补5个5
 */
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}

/**
 * 实现去补码,PKCS5Padding的反函数
 */
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
// 去掉最后一个字节 unpadding 次
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}

func main() {

orig := "Hello World!"
fmt.Println("原文:", orig)

//声明秘钥,利用此秘钥实现明文的加密和密文的解密,长度必须为8
key := "12345678"

//加密
encyptCode := MyDesEncrypt(orig, key)
fmt.Println("密文:", encyptCode)

//解密
decyptCode := MyDESDecrypt(encyptCode, key)
fmt.Println("解密结果:", decyptCode)
}

md5

image.png
package main
import (
"crypto/md5"
  "fmt"
  "encoding/base64"
)

func main() {
s:= []byte("123456789")
result := md5.Sum(s)
fmt.Println(base64.StdEncoding.EncodeToString(result[:]))
}
image.png

sha256

package main

import (
"fmt"
  "encoding/base64"
  "crypto/sha256"
)


func main() {
s:= []byte("123456789")
result := sha256.Sum256(s)
fmt.Println(base64.StdEncoding.EncodeToString(result[:]))
}
image.png

rsa

下面我们看一下dsa的签名过程

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

func main() {
  //rsa 密钥文件产生
  GenRsaKey(1024)
}
//RSA公钥私钥产生
func GenRsaKey(bits int) error {

  // 生成私钥文件
  privateKey, err := rsa.GenerateKey(rand.Reader, bits)
  if err != nil {
    return err
  }
  derStream := x509.MarshalPKCS1PrivateKey(privateKey)
  // 构造pem 结构
  block := &pem.Block{
    Type:  "RSA PRIVATE KEY",
    Bytes: derStream,
  }
  file, err := os.Create("private.pem")
  if err != nil {
    return err
  }
  
  // 将block 结构块 写入文件中
  err = pem.Encode(file, block)
  if err != nil {
    return err
  }

  // 生成公钥文件
  publicKey := &privateKey.PublicKey
  
  // 将公钥转换为 DER-encoded PKIX 格式
  derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
  if err != nil {
    return err
  }
  
  // 生成证书格式
  block = &pem.Block{
    Type:  "PUBLIC KEY",
    Bytes: derPkix,
  }
  file, err = os.Create("public.pem")
  if err != nil {
    return err
  }
  // 生成证书文件
  err = pem.Encode(file, block)
  if err != nil {
    return err
  }
  return nil
}

hmac

hmac包实现了U.S. Federal Information Processing Standards Publication 198规定的HMAC(加密哈希信息认证码)。

HMAC是使用key标记信息的加密hash。接收者使用相同的key逆运算来认证hash。

hmac主要应用在身份验证中,它的使用方法是这样的:
(1) 客户端发出登录请求(假设是浏览器的GET请求)
(2) 服务器返回一个随机值,并在会话中记录这个随机值
(3) 客户端将该随机值作为密钥,用户密码进行hmac运算,然后提交给服务器
(4) 服务器读取用户数据库中的用户密码和步骤2中发送的随机值做与客户端一样的hmac运算,然后与用户发送的结果比较,如果结果一致则验证用户合法

package main

import (
  "crypto/hmac"
  "crypto/sha256"
  "encoding/json"
  "fmt"
  "encoding/base64"
)

const key = "asdfasdfasdfasdf"
func main() {
   // 1.服务端发送一个token 给客户端
    serverSendKeyToClient(key)
}

func serverSendKeyToClient(key string){
  // 2.服务器将数据进行hmac 运算,
  keyHash := hmac.New(sha256.New,[]byte(key))
  data := map[string]string{"username":"xujie"}
  s,_:= json.Marshal(data)
  keyHash.Write([]byte(string(s)))

  expectedMAC := keyHash.Sum(nil)
  fmt.Println("客户端计算的hmac:")
  fmt.Println(base64.StdEncoding.EncodeToString(expectedMAC))

  // 3.将运算后的hash 值和数据发送给服务端 服务器
  clientSendMessageToServer(string(s),string(expectedMAC))

}

func clientSendMessageToServer(message,messageMac string){

  // 服务端接受数据后进行hmac 运算 如果结果和客户端传递过来的一致 就表示数据没有被篡改
  fmt.Println(CheckMAC([]byte(message),[]byte(messageMac),[]byte(key)))
  data := map[string]string{}
  json.Unmarshal([]byte(message),data)
  fmt.Println(message)
}

// 如果messageMAC是message的合法HMAC标签,函数返回真
func CheckMAC(message, messageMAC, key []byte) bool {
  mac := hmac.New(sha256.New, key)
  mac.Write(message)
  expectedMAC := mac.Sum(nil)
  fmt.Println("服务器计算的hmac:")
  fmt.Println(base64.StdEncoding.EncodeToString(expectedMAC))
  return hmac.Equal(messageMAC, expectedMAC)
}
image.png

rand

  • func Read(b []byte) (n int, err error)
package main

import (
    "fmt"
  "crypto/rand"
  "bytes"
)


func main() {

  c := 10
  b := make([]byte, c)
  
  // 生成随机数填满切片b
  _, err := rand.Read(b)
  if err != nil {
    fmt.Println("error:", err)
    return
  }
  fmt.Println(b)
  // 切片现在应该包含随机字节而不是仅包含零。
  fmt.Println(bytes.Equal(b, make([]byte, c)))
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • 这篇文章主要讲述在Mobile BI(移动商务智能)开发过程中,在网络通信、数据存储、登录验证这几个方面涉及的加密...
    雨_树阅读 2,233评论 0 6
  • 概述 之前一直对加密相关的算法知之甚少,只知道类似DES、RSA等加密算法能对数据传输进行加密,且各种加密算法各有...
    Henryzhu阅读 2,931评论 0 14
  • 在介绍加密算法之前, 先介绍一下 base64: 0. base64 Base64要求把每三个8Bit的字节转换为...
    reboot_q阅读 12,125评论 3 8
  • 目录介绍 1.加密和解密1.1 问答环节1.2 加解密概况 2.对称加密和非对称加密2.1 什么是对称加密2.2 ...
    杨充211阅读 765评论 0 6
  • 葱葱绿野绽,袅袅轻香燃。 山涧花相似,林中客不同。 年年冬觉迟,岁岁春来早。 一朝花隐退,万古木心静。
    抱一阅读 412评论 0 4