首页 > 作文

Go 加密解密算法小结

更新时间:2023-04-04 16:33:28 阅读: 评论:0

目录
前言md5hmacsha1aecb模式cbc模式crt模式cfb模式ofb模式rsa加密参考:

前言

加密解密在实际开发中应用比较广泛,常用加解密分为:“对称式”、“非对称式”和”数字签名“。

对称式:对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。具体算法主要有des算法,3des算法,tdea算法,blowfish算法,rc5算法,idea算法。

非对称加密(公钥加密):指加密和解密使用不同密钥的加密算法,也称为公私钥加密。具体算法主要有rsa、elgamal、背包算法、rabin、d-h、ecc(椭圆曲线加密算法)。

数字签名:数字签名是非对称密钥加密技术与数字摘要技术的应用。主要算法有md5、hmac、sha1等。

以下介绍golang语言主要的加密解密算法实现。

md5

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

func getmd5string(s string) string {    h := md5.new()    轮台歌奉送封大夫出师西征h.write([]byte(s))    return hex.encodetostring(h.sum(nil))}

hmac

hmac是密钥相关的哈希运算消息认证码(hash-bad message authentication code)的缩写,

它通过一个标准算法,在计算哈希的过程中,把key混入计算过程中。

和我们自定义的加salt算法不同,hmac算法针对所有哈希算法都通用,无论是md5还是sha-1。采用hmac替代我们自己的salt算法,可以使程序算法更标准化,也更安全。

示例

//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("")))}func hmacsha256(key, data string) string {    hash:= hmac.new(sha256.new, []byte(key)) //创建对应的sha256哈希加密算法    hash.write([]byte(data))    return hex.encodetostring(hash.sum([]byte("")))}

sha1

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

func sha1(data string) string {    sha1 := sha1.new()    sha1.write([]byte(data))    return hex.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模式。

package mainimport ( "crypto/aes" "fmt")func aencrypt(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)) for i := len(src); i < len(plain); i++ {  plain[i] = pad } encrypted = make([]byte, len(plain)) // 分组分块加密 for bs, be := 0, cipher.blocksize(); bs <= len(src); bs, be = bs+cipher.blocksize(), be+cipher.blocksize() {  cipher.encrypt(encrypted[bs:be], plain[bs:be]) } return encrypted}func aesdecrypt(encrypted []byt突然和忽然有什么区别e, 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.dec校园宣讲会rypt(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() { source:="hello world" fmt.println("原字符:",source) //16byte密钥 key:="1443flfsawfdas" encryptcode:=aencrypt([]byte(source),[]byte(key)) fmt.println("密宿舍床尺寸文:",string(encryptcode)) decryptcode:=aesdecrypt(encryptcode,[]byte(key)) fmt.println("解密:",string(decryptcode))}

cbc模式

package mainimport(  "bytes"  "crypto/aes"  "fmt"  "crypto/cipher"  "encoding/ba64")func main() {  orig := "hello world"  key := "0123456789012345"  fmt.println("原文:", orig)  encryptcode := aencrypt(orig, key)  fmt.println("密文:" , encryptcode)  decryptcode := aesdecrypt(encryptcode, key)  fmt.println("解密结果:", decryptcode)}func aencrypt(orig string, key string) 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)  return ba64.stdencoding.encodetostring(cryted)}func aesdecrypt(cryted string, key string) string {  // 转成字节数组  crytedbyte, _ := ba64.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)  return string(orig)}//补码//aes加密数据块分组长度必须为128bit(byte[16]),密钥长度可以是128bit(byte[16])、192bit(byte[24])、256bit(byte[32])中的任意一个。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)]}

crt模式

package mainimport ( "bytes" "crypto/aes" "crypto/cipher" "fmt")//加密func aesctrcrypt(plaintext []byte, key []byte) ([]byte, error) { //1. 创建cipher.block接口 block, err := aes.newcipher(key) if err != nil {  return nil, 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) return dst, nil}func main() { source:="hello world" 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模式

package mainimport ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/hex" "fmt" "io")func aencryptcfb(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.xorkeystre汉中八景am(encrypted, encrypted) return encrypted}func main() { source:="hello world" fmt.println("原字符:",source) key:="abcdefghijklmno1"//16位 encryptcode:=aencryptcfb([]byte(source),[]byte(key)) fmt.println("密文:",hex.encodetostring(encryptcode)) decryptcode:=aesdecryptcfb(encryptcode,[]byte(key)) fmt.println("解密:",string(decryptcode))}

ofb模式

package mainimport ( "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/hex" "fmt" "io")func aencryptofb( data[]byte,key []byte) ([]byte, error) { data = pkcs7padding(data, aes.blocksize) block, _ := aes.newcipher([]byte(key)) out := make([]byte, aes.blocksize + len(data)) iv := out[:aes.blocksize] if _, err := io.readfull(rand.reader, iv); err != nil {  return nil, err } stream := cipher.newofb(block, iv) stream.xorkeystream(out[aes.blocksize:], data) return out, nil}func aesdecryptofb( data[]byte,key []byte) ([]byte, error) { block, _ := aes.newcipher([]byte(key)) iv := data[:aes.blocksize] data = data[aes.blocksize:] if len(data) % aes.blocksize != 0 {  return nil, fmt.errorf("data is not a multiple of the block size") } out := make([]byte, len(data)) mode := cipher.newofb(block, iv) mode.xorkeystream(out, data) out= pkcs7unpadding(out) return out, nil}//补码//aes加密数据块分组长度必须为128bit(byte[16]),密钥长度可以是128bit(byte[16])、192bit(byte[24])、256bit(byte[32])中的任意一个。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)]}func main() { source:="hello world" fmt.println("原字符:",source) key:="1111111111111111"//16位 32位均可 encryptcode,_:=aencryptofb([]byte(source),[]byte(key)) fmt.println("密文:",hex.encodetostring(encryptcode)) decryptcode,_:=aesdecryptofb(encryptcode,[]byte(key)) fmt.println("解密:",string(decryptcode))}

rsa加密

首先使用openssl生成公私钥

package mainimport ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/ba64" "encoding/pem" "errors" "fmt")// 私钥生成//openssl genrsa -out rsa_private_key.pem 1024var privatekey = []byte(`-----begin rsa private key-----miicwwibaakbgqdcgsuiiainhfrtdmmggwlrjzfmnsrtgif4egsnaywmc1gjf/bmh0mcm10olhnrknycttqvggixuc5hekd1gozb7bdtncdppz7ov7p1b9pud+6zpacoqdz2m24vhfwyy2fbiijh8fhhkcfxnxolovdvbe7zy682x1+r1lrk8d+vmqidaqabaogaewazvz1hzexca5k/hpbeqv+0+vtobmgwms96+u53bpo/vrzl8cu3cpnyb7hy64l9yq+j5qgpphqkgio0dmu/0rixsmhvr2gcxmkobcqt3jq6s4rjhtln49i2sytz7jeh4tcplkjsjhyq5mhhfa+cv2/ab2bo6g8limu7shexuvecqqdwopzrzdetoobkz1vercawd+j9ll/fzyttnrwyti1ssf1snfz7duxpyypqfz0lq1bhzgmwbz6a6wd9r+pklmjvakea6o32c/wexxw2zeh18soo4wquibyq3l3hfobhcsuay8jfykqefw8qypuul02jliajfwd0itjvirzwnvmouuxydwjaxglrvllivkilah+latprkyph3gycyfnxctnkozivoxmjgp6wmfylgiflpzdsuiapnxby1fnm7987fh7lp/m12qjak9il2jntwksr3p305oouaz0oforn8mnb+kfmramt9pnhwk0vke0lb1sc7ztkyvkejw0oeqgic9dviyzwducu8wjaikkrozuzli9avlnlursdi6998lmeyo9x7pwzpukz3erazncjrk3pbvkv0krkfczujirlz7duzvo0b6qjr8traa==-----end rsa private key-----`)// 公钥: 根据私钥生成//openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pemvar publickey = []byte(`-----begin public key-----migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqdcgsuiiainhfrtdmmggwlrjzfmnsrtgif4egsnaywmc1gjf/bmh0mcm10olhnrknycttqvggixuc5hekd1gozb7bdtncdppz7ov7p1b9pud+6zpacoqdz2m24vhfwyy2fbiijh8fhhkcfxnxolovdvbe7zy682x1+r1lrk8d+vmqidaqab-----end public key-----`)// 加密func rsaencrypt(origdata []byte) ([]byte, error) { //解密pem格式的公钥 block, _ := pem.decode(publickey) if block == nil {  return nil, errors.new("public key error") } // 解析公钥 pubinterface, err := x509.parpkixpublickey(block.bytes) if err != nil {  return nil, err } // 类型断言 pub := pubinterface.(*rsa.publickey) //加密 return rsa.encryptpkcs1v15(rand.reader, pub, origdata)}// 解密func rsadecrypt(ciphertext []byte) ([]byte, error) { //解密 block, _ := pem.decode(privatekey) if block == nil {  return nil, errors.new("private key error!") } //解析pkcs1格式的私钥 priv, err := x509.parpkcs1privatekey(block.bytes) if err != nil {  return nil, err } // 解密 return rsa.decryptpkcs1v15(rand.reader, priv, ciphertext)}func main() { data, _ := rsaencrypt([]byte("hello world")) fmt.println(ba64.stdencoding.encodetostring(data)) origdata, _ := rsadecrypt(data) fmt.println(string(origdata))}

参考:

https://www.liaoxuefeng.com/wiki/1016959663602400/1183198304823296

https://studygolang.com/articles/15642?fr=sidebar

https://gmentfault.com/a/1190000004151272

到此这篇关于go 加密解密算法小结的文章就介绍到这了,更多相关go 加密解密内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 16:33:26,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/ba606282deeae62c2bfb71eb7d824897.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Go 加密解密算法小结.doc

本文 PDF 下载地址:Go 加密解密算法小结.pdf

标签:算法   模式   密钥   长度
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图