前语
加密解密在实践开发中运用比较广泛,常用加解密分为:“对称式”、“非对称式”和”数字签名“。
对称式:对称加密(也叫私钥加密)指加密宽和密运用相同密钥的加密算法。详细算法首要有DES算法,3DES算法,TDEA算法,Blowfish算法,RC5算法,IDEA算法。
非对称加密(公钥加密):指加密宽和密运用不同密钥的加密算法,也称为公私钥加密。详细算法首要有RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)。
数字签名:数字签名对错对称密钥加密技能与数字摘要技能的运用。首要算法有md5、hmac、sha1等。
以下介绍golang言语首要的加密解密算法完成。
md5
MD5信息摘要算法是一种被广泛运用的暗码散列函数,能够产生出一个128位(16进制,32个字符)的散列值(hash value),用于保证信息传输完好共同。
- funcGetMd5String(sstring)string{
- h:=md5.New()
- h.Write([]byte(s))
- returnhex.EncodeToString(h.Sum(nil))
- }
hmac
HMAC是密钥相关的哈希运算音讯认证码(Hash-based Message Authentication Code)的缩写,
它经过一个规范算法,在核算哈希的过程中,把key混入核算过程中。
和咱们自定义的加salt算法不同,Hmac算法针对一切哈希算法都通用,无论是MD5仍是SHA-1。选用Hmac代替咱们自己的salt算法,能够使程序算法更规范化,也更安全。
示例
- //key随意设置data要加密数据
- funcHmac(key,datastring)string{
- hash:=hmac.New(md5.New,[]byte(key))//创立对应的md5哈希加密算法
- hash.Write([]byte(data))
- returnhex.EncodeToString(hash.Sum([]byte("")))
- }
- funcHmacSha256(key,datastring)string{
- hash:=hmac.New(sha256.New,[]byte(key))//创立对应的sha256哈希加密算法
- hash.Write([]byte(data))
- returnhex.EncodeToString(hash.Sum([]byte("")))
- }
sha1
SHA-1能够生成一个被称为音讯摘要的160位(20字节)散列值,散列值一般的出现方式为40个十六进制数。
- funcSha1(datastring)string{
- sha1:=sha1.New()
- sha1.Write([]byte(data))
- returnhex.EncodeToString(sha1.Sum([]byte("")))
- }
AES
暗码学中的高档加密规范(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府选用的一种区块加密规范。这个规范用来代替原先的DES(Data Encryption Standard),现已被多方剖析且广为全世界所运用。AES中常见的有三种解决方案,分别为AES-128、AES-192和AES-256。假如选用真实的128位加密技能乃至256位加密技能,蛮力进犯要取得成功需求消耗适当长的时刻。
AES 有五种加密形式:
- 电码本形式(Electronic Codebook Book (ECB))、
- 暗码分组链接形式(Cipher Block Chaining (CBC))、
- 核算器形式(Counter (CTR))、
- 暗码反应形式(Cipher FeedBack (CFB))
- 输出反应形式(Output FeedBack (OFB))
ECB形式
出于安全考虑,golang默许并不支撑ECB形式。
- packagemain
- import(
- "crypto/aes"
- "fmt"
- )
- funcAESEncrypt(src[]byte,key[]byte)(encrypted[]byte){
- cipher,_:=aes.NewCipher(generateKey(key))
- length:=(len(src)+aes.BlockSize)/aes.BlockSize
- plain:=make([]byte,length*aes.BlockSize)
- copy(plain,src)
- pad:=byte(len(plain)-len(src))
- fori:=len(src);i<len(plain);i++{
- plain[i]=pad
- }
- encrypted=make([]byte,len(plain))
- //分组分块加密
- forbs,be:=0,cipher.BlockSize();bs<=len(src);bs,be=bs+cipher.BlockSize(),be+cipher.BlockSize(){
- cipher.Encrypt(encrypted[bs:be],plain[bs:be])
- }
- returnencrypted
- }
- funcAESDecrypt(encrypted[]byte,key[]byte)(decrypted[]byte){
- cipher,_:=aes.NewCipher(generateKey(key))
- decrypted=make([]byte,len(encrypted))
- //
- forbs,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
- iflen(decrypted)>0{
- trim=len(decrypted)-int(decrypted[len(decrypted)-1])
- }
- returndecrypted[:trim]
- }
- funcgenerateKey(key[]byte)(genKey[]byte){
- genKey=make([]byte,16)
- copy(genKey,key)
- fori:=16;i<len(key);{
- forj:=0;j<16&&i<len(key);j,i=j+1,i+1{
- genKey[j]^=key[i]
- }
- }
- returngenKey
- }
- funcmain(){
- source:="helloworld"
- fmt.Println("原字符:",source)
- //16byte密钥
- key:="1443flfsaWfdas"
- encryptCode:=AESEncrypt([]byte(source),[]byte(key))
- fmt.Println("密文:",string(encryptCode))
- decryptCode:=AESDecrypt(encryptCode,[]byte(key))
- fmt.Println("解密:",string(decryptCode))
- }
CBC形式
- packagemain
- import(
- "bytes"
- "crypto/aes"
- "fmt"
- "crypto/cipher"
- "encoding/base64"
- )
- funcmain(){
- orig:="helloworld"
- key:="0123456789012345"
- fmt.Println("原文:",orig)
- encryptCode:=AesEncrypt(orig,key)
- fmt.Println("密文:",encryptCode)
- decryptCode:=AesDecrypt(encryptCode,key)
- fmt.Println("解密成果:",decryptCode)
- }
- funcAesEncrypt(origstring,keystring)string{
- //转成字节数组
- origData:=[]byte(orig)
- k:=[]byte(key)
- //分组秘钥
- //NewCipher该函数约束了输入k的长度有必要为16,24或许32
- block,_:=aes.NewCipher(k)
- //获取秘钥块的长度
- blockSize:=block.BlockSize()
- //补全码
- origData=PKCS7Padding(origData,blockSize)
- //加密形式
- blockMode:=cipher.NewCBCEncrypter(block,k[:blockSize])
- //创立数组
- cryted:=make([]byte,len(origData))
- //加密
- blockMode.CryptBlocks(cryted,origData)
- returnbase64.StdEncoding.EncodeToString(cryted)
- }
- funcAesDecrypt(crytedstring,keystring)string{
- //转成字节数组
- crytedByte,_:=base64.StdEncoding.DecodeString(cryted)
- k:=[]byte(key)
- //分组秘钥
- block,_:=aes.NewCipher(k)
- //获取秘钥块的长度
- blockSize:=block.BlockSize()
- //加密形式
- blockMode:=cipher.NewCBCDecrypter(block,k[:blockSize])
- //创立数组
- orig:=make([]byte,len(crytedByte))
- //解密
- blockMode.CryptBlocks(orig,crytedByte)
- //去补全码
- orig=PKCS7UnPadding(orig)
- returnstring(orig)
- }
- //补码
- //AES加密数据块分组长度有必要为128bit(byte[16]),密钥长度能够是128bit(byte[16])、192bit(byte[24])、256bit(byte[32])中的恣意一个。
- funcPKCS7Padding(ciphertext[]byte,blocksizeint)[]byte{
- padding:=blocksize-len(ciphertext)%blocksize
- padtext:=bytes.Repeat([]byte{byte(padding)},padding)
- returnappend(ciphertext,padtext...)
- }
- //去码
- funcPKCS7UnPadding(origData[]byte)[]byte{
- length:=len(origData)
- unpadding:=int(origData[length-1])
- returnorigData[:(length-unpadding)]
- }
CRT形式
- packagemain
- import(
- "bytes"
- "crypto/aes"
- "crypto/cipher"
- "fmt"
- )
- //加密
- funcaesCtrCrypt(plainText[]byte,key[]byte)([]byte,error){
- //1.创立cipher.Block接口
- block,err:=aes.NewCipher(key)
- iferr!=nil{
- returnnil,err
- }
- //2.创立分组形式,在crypto/cipher包中
- iv:=bytes.Repeat([]byte("1"),block.BlockSize())
- stream:=cipher.NewCTR(block,iv)
- //3.加密
- dst:=make([]byte,len(plainText))
- stream.XORKeyStream(dst,plainText)
- returndst,nil
- }
- funcmain(){
- source:="helloworld"
- fmt.Println("原字符:",source)
- key:="1443flfsaWfdasds"
- encryptCode,_:=aesCtrCrypt([]byte(source),[]byte(key))
- fmt.Println("密文:",string(encryptCode))
- decryptCode,_:=aesCtrCrypt(encryptCode,[]byte(key))
- fmt.Println("解密:",string(decryptCode))
- }
- CFB形式
- packagemain
- import(
- "crypto/aes"
- "crypto/cipher"
- "crypto/rand"
- "encoding/hex"
- "fmt"
- "io"
- )
- funcAesEncr