GoLang中的加密方法小結(jié)
GoLang加密方法
以下Golang代碼的加密結(jié)果與Java語言結(jié)果一致,需要注意結(jié)果大小寫問題。
package tool ? import ( ? ? "appback/src/logger" ? ? "bytes" ? ? "crypto/aes" ? ? "crypto/cipher" ? ? "crypto/hmac" ? ? "crypto/md5" ? ? "crypto/rand" ? ? "crypto/rsa" ? ? "crypto/sha1" ? ? "crypto/sha256" ? ? "crypto/sha512" ? ? "crypto/x509" ? ? "encoding/base64" ? ? "encoding/hex" ? ? "encoding/pem" ? ? "fmt" ? ? "strings" ) ? // md5驗(yàn)證 func MD5Str(src string) string { ? ? h := md5.New() ? ? h.Write([]byte(src)) // 需要加密的字符串為 ? ? // fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 輸出加密結(jié)果 ? ? return hex.EncodeToString(h.Sum(nil)) } ? // hmacsha256驗(yàn)證 func HMAC_SHA256(src, key string) string { ? ? m := hmac.New(sha256.New, []byte(key)) ? ? m.Write([]byte(src)) ? ? return hex.EncodeToString(m.Sum(nil)) } ? // hmacsha512驗(yàn)證 func HMAC_SHA512(src, key string) string { ? ? m := hmac.New(sha512.New, []byte(key)) ? ? m.Write([]byte(src)) ? ? return hex.EncodeToString(m.Sum(nil)) } ? func HMAC_SHA1(src, key string) string { ? ? m := hmac.New(sha1.New, []byte(key)) ? ? m.Write([]byte(src)) ? ? return hex.EncodeToString(m.Sum(nil)) } ? // sha256驗(yàn)證 func SHA256Str(src string) string { ? ? h := sha256.New() ? ? h.Write([]byte(src)) // 需要加密的字符串為 ? ? // fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 輸出加密結(jié)果 ? ? return hex.EncodeToString(h.Sum(nil)) } ? // sha512驗(yàn)證 func SHA512Str(src string) string { ? ? h := sha512.New() ? ? h.Write([]byte(src)) // 需要加密的字符串為 ? ? // fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 輸出加密結(jié)果 ? ? return hex.EncodeToString(h.Sum(nil)) } ? // base編碼 func BASE64EncodeStr(src string) string { ? ? return string(base64.StdEncoding.EncodeToString([]byte(src))) } ? // base解碼 func BASE64DecodeStr(src string) string { ? ? a, err := base64.StdEncoding.DecodeString(src) ? ? if err != nil { ? ? ? ? return "" ? ? } ? ? return string(a) } ? var ivspec = []byte("0000000000000000") ? func AESEncodeStr(src, key string) string { ? ? block, err := aes.NewCipher([]byte(key)) ? ? if err != nil { ? ? ? ? fmt.Println("key error1", err) ? ? } ? ? if src == "" { ? ? ? ? fmt.Println("plain content empty") ? ? } ? ? ecb := cipher.NewCBCEncrypter(block, ivspec) ? ? content := []byte(src) ? ? content = PKCS5Padding(content, block.BlockSize()) ? ? crypted := make([]byte, len(content)) ? ? ecb.CryptBlocks(crypted, content) ? ? return hex.EncodeToString(crypted) } ? func AESDecodeStr(crypt, key string) string { ? ? crypted, err := hex.DecodeString(strings.ToLower(crypt)) ? ? if err != nil || len(crypted) == 0 { ? ? ? ? fmt.Println("plain content empty") ? ? } ? ? block, err := aes.NewCipher([]byte(key)) ? ? if err != nil { ? ? ? ? fmt.Println("key error1", err) ? ? } ? ? ecb := cipher.NewCBCDecrypter(block, ivspec) ? ? decrypted := make([]byte, len(crypted)) ? ? ecb.CryptBlocks(decrypted, crypted) ? ? ? return string(PKCS5Trimming(decrypted)) } ? func PKCS5Padding(ciphertext []byte, blockSize int) []byte { ? ? padding := blockSize - len(ciphertext)%blockSize ? ? padtext := bytes.Repeat([]byte{byte(padding)}, padding) ? ? return append(ciphertext, padtext...) } ? func PKCS5Trimming(encrypt []byte) []byte { ? ? padding := encrypt[len(encrypt)-1] ? ? return encrypt[:len(encrypt)-int(padding)] } ? func RsaEncrypt(src, key string) string { ? ? block, _ := pem.Decode([]byte(key)) ? ? if block == nil { ? ? ? ? return "" ? ? } ? ? ? pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) ? ? if err != nil { ? ? ? ? logger.SysLogger.Err(err.Error()) ? ? ? ? return "" ? ? } ? ? ? pub := pubInterface.(*rsa.PublicKey) ? ? ? crypted, err := rsa.EncryptPKCS1v15(rand.Reader, pub, []byte(src)) ? ? if err != nil { ? ? ? ? logger.SysLogger.Err(err.Error()) ? ? ? ? return "" ? ? } ? ? ? return hex.EncodeToString(crypted) }
調(diào)用
package main ? import ( ?? ?"./tool" ?? ?"fmt" ) ? func main() { ?? ?fmt.Printf(tool.MD5Str("111")) }
GoLang三類加密算法
哈希算法
名稱 | 速度/安全性 |
---|---|
crc32 | 速度快,安全性低 2^32 |
adler | 速度快,安全性低 2^32 |
crc64 | 速度稍微快,安全性低 2^64 |
md5 | 速度一般,安全性一般 2^128 |
sha1 | 速度一般,安全性一般 2^128 |
sha256 | 速度慢安全性高 2^256 |
sha512 | 速度慢,安全性極高 2^512 |
hash函數(shù)應(yīng)用:
消息認(rèn)證是用來驗(yàn)證消息完整性的一種機(jī)制或服務(wù),消息認(rèn)證確認(rèn)收到的數(shù)據(jù)確實(shí)和發(fā)送時的一樣(即防篡改),并且還要確保發(fā)送方的身份是真實(shí)有效的的(即防冒充)。
也就是說哈希函數(shù)只是確定信息來自生產(chǎn)者,只有驗(yàn)證功能,不可用于信息傳輸,因?yàn)闆]有解密算法。
表格中算法的golang實(shí)現(xiàn)
import 包 :
import ( ?? ?"hash/crc32" ?? ?"hash/crc64" ?? ?"hash/adler32" ?? ?"crypto/sha512" ?? ?"crypto/sha256" ?? ?"crypto/sha1" ?? ?"crypto/md5" ?? ?"encoding/hex" )
老師說用于驗(yàn)證的哈希函數(shù),一般不單個用,定義加密接口的時候,定義一個[]string用于存放組合的哈希函數(shù)的名字,如:[]string{“md5",“crc64”,“sha256”.“sha256”······}
type AllHash struct { ?? ?Alog []string }
綁定方法根據(jù)哈希名字將數(shù)據(jù)哈希化,這些函數(shù)被Go標(biāo)準(zhǔn)庫給敷衍了,解釋在十個字以內(nèi),要不就沒有,我giao
對于md5,sha1,sha256,sha512步驟一樣,
我猜:
(以md5為例)
1.New一個的對象,相當(dāng)于申請了一塊buf:myhash:=md5.New()
2.向這個buf中寫入字節(jié)類型的數(shù)據(jù):myhash.Write([]byte(laststr))
3.進(jìn)行相應(yīng)的哈希運(yùn)算:bs:=myhash.Sum(nil),我用反射查看bs的類型是[]uint8.
4.最終數(shù)據(jù)以16進(jìn)制輸出 :laststr=hex.EncodeToString(bs)或者fmt.Sprintf("%x", bs)
func (allhash *AllHash)GetBytesHash(data[]byte)string{ ?? ?var laststr string ?? ?laststr=string(data) ?? ?for i:=0;i<len(allhash.Alog);i++{ ?? ??? ?switch allhash.Alog[i] { ?? ??? ?case "md5": ?? ??? ??? ?myhash:=md5.New() ?? ??? ??? ?myhash.Write([]byte(laststr)) ?? ??? ??? ?bs:=myhash.Sum(nil) ?? ??? ??? ?laststr=hex.EncodeToString(bs) ?? ??? ?case "sha1": ?? ??? ??? ?myhash:=sha1.New() ?? ??? ??? ?myhash.Write([]byte(laststr)) ?? ??? ??? ?bs:=myhash.Sum(nil) ?? ??? ??? ?laststr=hex.EncodeToString(bs) ?? ??? ?case "sha256": ?? ??? ??? ?myhash:=sha256.New() ?? ??? ??? ?myhash.Write([]byte(laststr)) ?? ??? ??? ?bs:=myhash.Sum(nil) ?? ??? ??? ?laststr=hex.EncodeToString(bs) ?? ??? ?case "sha512": ?? ??? ??? ?myhash:=sha512.New() ?? ??? ??? ?myhash.Write([]byte(laststr)) ?? ??? ??? ?bs:=myhash.Sum(nil) ?? ??? ??? ?laststr=hex.EncodeToString(bs) ?? ??? ?case "crc32": ?? ??? ??? ?mycrc:=crc32.NewIEEE() ?? ??? ??? ?io.WriteString(mycrc,laststr) ?? ??? ??? ?laststr=fmt.Sprintf("%x",mycrc.Sum32()) ?? ??? ?case "crc64": ?? ??? ??? ?const ISO = 0xD800000000000000 ?? ??? ??? ?tabISO := MakeTable(ISO) ?? ??? ??? ?c := crc64.New(tabISO) ?? ??? ??? ?io.WriteString(c, laststr) ?? ??? ??? ?s := c.Sum64() ?? ??? ??? ?laststr=fmt.Sprintf("%x",s) ?? ??? ?case "adler32": ?? ??? ??? ?c := adler32.New() ?? ??? ??? ?io.WriteString(c, laststr) ?? ??? ??? ?state, err := c.(encoding.BinaryMarshaler).MarshalBinary() ?? ??? ??? ?if err!=nil{ ?? ??? ??? ??? ?fmt.Println(err) ?? ??? ??? ?} ?? ??? ??? ?laststr=hex.EncodeToString(state) ?? ??? ??? ?} }
對稱加密
對稱加密,消息發(fā)送端要先有一個密鑰,然后執(zhí)行加密算法,獲得加密數(shù)據(jù);接受端要事先獲得發(fā)送者的密鑰,用密鑰進(jìn)行解密。
對稱加密適合對大量數(shù)據(jù)進(jìn)行加密,由于傳輸密鑰并不安全,真正使用時,對數(shù)據(jù)進(jìn)行對稱加密,對密鑰進(jìn)行非對稱加密。
DES加密步驟:
- 1.確定密鑰位數(shù),不夠的補(bǔ)零,超了截。這里假設(shè)密鑰是24位
- 2.調(diào)用第三方庫goEncrypt的TripleDesEncrypt,利用密鑰進(jìn)行加密
- 3.返回加密數(shù)據(jù)。
func Encrypt(datastr []byte,password []byte)[]byte { ?? ?length:=len(password) ?? ?if length<24{ ?? ??? ?for i:=0;i<=24-1-length;i++{ ?? ??? ??? ?password=append(password,0) ?? ??? ?} ?? ?}else if length>24 { ?? ??? ?password=password[:24] ?? ?} ?? ?cryptText, err := goEncrypt.TripleDesEncrypt(datastr, password) ?? ?if err != nil { ?? ??? ?fmt.Println(err) ?? ??? ?return []byte{} ?? ?} ?? ?return cryptText }
DES解密步驟:
- 1.確定密鑰位數(shù),不夠的補(bǔ)零,超了截。這里假設(shè)密鑰是24位
- 2.調(diào)用第三方庫goEncrypt的TripleDesDecrypt,利用密鑰進(jìn)行解密
- 3.返回解密數(shù)據(jù)
func Decrypt(datastr []byte,password []byte)[]byte ?{ ?? ?length:=len(password) ?? ?if length<24{ ?? ??? ?for i:=0;i<=24-1-length;i++{ ?? ??? ??? ?password=append(password,0) ?? ??? ?} ?? ?}else if length>24 { ?? ??? ?password=password[:24] ?? ?} ?? ?//fmt.Println(len(password)) ?? ?newplaintext, err:= goEncrypt.TripleDesDecrypt(datastr, password) ?? ?if err != nil { ?? ??? ?fmt.Println(err) ?? ??? ?return []byte{} ?? ?} ?? ?return newplaintext }
非對稱加密
私鑰加密,公鑰解密;公鑰加密,私鑰解密,稱之為非對稱加密。
雙方進(jìn)行信息傳遞,雙方都需要創(chuàng)建公鑰和私鑰,如果己方用私鑰加密,就要把公鑰傳給對方,對方用公鑰解密。
下面是ECCgolang實(shí)現(xiàn):
func (e *ECC )Encrypt(datastr []byte)[]byte { ?? ?cryptText, err:= goEncrypt.EccEncrypt(datastr , []byte(e.publickey)) ?? ?if err!=nil{ ?? ??? ?return []byte{} ?? ?} ?? ?return cryptText } func (e *ECC )Decrypt(datastr []byte)[]byte ?{ ?? ?msg, err := goEncrypt.EccDecrypt(datastr , []byte(e.privatekey)) ?? ?if err != nil { ?? ??? ?return []byte{} ?? ?} ?? ?return msg }
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
go程序測試CPU占用率統(tǒng)計(jì)ps?vs?top兩種不同方式對比
這篇文章主要為大家介紹了go程序測試CPU占用率統(tǒng)計(jì)ps?vs?top兩種不同方式對比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05Go語言中的goroutine和channel如何協(xié)同工作
在Go語言中,goroutine和channel是并發(fā)編程的兩個核心概念,它們協(xié)同工作以實(shí)現(xiàn)高效、安全的并發(fā)執(zhí)行,本文將詳細(xì)探討goroutine和channel如何協(xié)同工作,以及它們在并發(fā)編程中的作用和優(yōu)勢,需要的朋友可以參考下2024-04-04go語言beego框架jwt身份認(rèn)證實(shí)現(xiàn)示例
這篇文章主要為大家介紹了go語言beego框架jwt身份認(rèn)證實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04利用go語言實(shí)現(xiàn)Git?重命名遠(yuǎn)程分支??
這篇文章主要介紹了go語言實(shí)現(xiàn)Git?重命名遠(yuǎn)程分支,文章基于go語言的基礎(chǔ)展開Git?重命名遠(yuǎn)程分支的實(shí)現(xiàn)過程,需要的小伙伴可以參考一下,希望對你的學(xué)習(xí)有所幫助2022-06-06Golang?Gin框架獲取請求參數(shù)的幾種常見方式
在我們平常添加路由處理函數(shù)之后,就可以在路由處理函數(shù)中編寫業(yè)務(wù)處理代碼了,但在此之前我們往往需要獲取請求參數(shù),本文就詳細(xì)的講解下gin獲取請求參數(shù)常見的幾種方式,需要的朋友可以參考下2024-02-02通過函數(shù)如何將golang?float64?保留2位小數(shù)(方法匯總)
這篇文章主要介紹了通過函數(shù)將golang?float64保留2位小數(shù),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08