Go語言實(shí)現(xiàn)AES加密并編寫一個(gè)命令行應(yīng)用程序
什么是AES
關(guān)于AES更多的知識(shí),請自行腦補(bǔ),密碼學(xué)中的高級(jí)加密標(biāo)準(zhǔn)(Advanced Encryption Standard,AES),又稱Rijndael加密法,是經(jīng)常采用的一種區(qū)塊加密標(biāo)準(zhǔn)。
go實(shí)現(xiàn)aes加密
在golang的標(biāo)準(zhǔn)庫aes可以實(shí)現(xiàn)AES加密,官方標(biāo)準(zhǔn)庫aes文檔鏈接:https://pkg.go.dev/crypto/aes
小案例需求
本篇分享出在實(shí)際工作中的實(shí)際需求,需求很簡單,就是需要實(shí)現(xiàn)一個(gè)命令行應(yīng)用程序,可以對(duì)傳入的明文字符串進(jìn)行加密,傳入密文進(jìn)行解密。命令行應(yīng)用叫做passctl,并帶有幫助功能。實(shí)現(xiàn)命令行應(yīng)用程序有很多強(qiáng)大的第三方庫,因?yàn)樾枨筮^于簡單,那么本篇就用標(biāo)準(zhǔn)庫中os即可。
實(shí)戰(zhàn)
加密代碼
package?main
import?(
?"bytes"
?"crypto/aes"
?"crypto/cipher"
?"encoding/base64"
?"fmt"
)
var?EncKey?=?[]byte("QAZWSXEDCRFVTGBY")?//?16位密碼串
func?pkcs7Padding(data?[]byte,?blockSize?int)?[]byte?{
?padding?:=?blockSize?-?len(data)%blockSize
?padText?:=?bytes.Repeat([]byte{byte(padding)},?padding)
?return?append(data,?padText...)
}
func?AesEncrypt(data?[]byte,?key?[]byte)?([]byte,?error)?{
?block,?err?:=?aes.NewCipher(key)
?if?err?!=?nil?{
??return?nil,?err
?}
?blockSize?:=?block.BlockSize()
?encryptBytes?:=?pkcs7Padding(data,?blockSize)
?crypted?:=?make([]byte,?len(encryptBytes))
?blockMode?:=?cipher.NewCBCEncrypter(block,?key[:blockSize])
?blockMode.CryptBlocks(crypted,?encryptBytes)
?return?crypted,?nil
}
func?EncryptByAes(data?[]byte)?(string,?error)?{
?res,?err?:=?AesEncrypt(data,?EncKey)
?if?err?!=?nil?{
??return?"",?err
?}
?return?base64.StdEncoding.EncodeToString(res),?nil
}
func?main()?{
?plaintext?:=?"2wsx$RFV!Qaz"?//?假設(shè)這是明文密碼
?p?:=?[]byte(plaintext)
?newp,?_?:=?EncryptByAes(p)?//?開始加密
?fmt.Println(newp)
}
解密代碼
基于上述加密后的密碼,對(duì)其進(jìn)行解密。
package?main
import?(
?"crypto/aes"
?"crypto/cipher"
?"encoding/base64"
?"errors"
?"fmt"
)
var?EncKey?=?[]byte("QAZWSXEDCRFVTGBY")?//?16位密碼串
func?pkcs7UnPadding(data?[]byte)?([]byte,?error)?{
?length?:=?len(data)
?if?length?==?0?{
??return?nil,?errors.New("Sorry,?the?encryption?string?is?wrong.")
?}
?unPadding?:=?int(data[length-1])
?return?data[:(length?-?unPadding)],?nil
}
func?AesDecrypt(data?[]byte,?key?[]byte)?([]byte,?error)?{
?block,?err?:=?aes.NewCipher(key)
?if?err?!=?nil?{
??return?nil,?err
?}
?blockSize?:=?block.BlockSize()
?blockMode?:=?cipher.NewCBCDecrypter(block,?key[:blockSize])
?crypted?:=?make([]byte,?len(data))
?blockMode.CryptBlocks(crypted,?data)
?crypted,?err?=?pkcs7UnPadding(crypted)
?if?err?!=?nil?{
??return?nil,?err
?}
?return?crypted,?nil
}
func?DecryptByAes(data?string)?([]byte,?error)?{
?dataByte,?err?:=?base64.StdEncoding.DecodeString(data)
?if?err?!=?nil?{
??return?nil,?err
?}
?return?AesDecrypt(dataByte,?EncKey)
}
func?main()?{
?ciphertext?:=?"+LxjKS8N+Kpy/HNxsSJMIw=="?//?密文
?pwd,?_?:=?DecryptByAes(ciphertext)???????//?開始解密
?fmt.Println(string(pwd))
}
實(shí)現(xiàn)passctl命令行應(yīng)用
代碼
package?main
import?(
?"bytes"
?"crypto/aes"
?"crypto/cipher"
?"encoding/base64"
?"errors"
?"fmt"
?"os"
)
var?EncKey?=?[]byte("QAZWSXEDCRFVTGBY")?//?16位密碼串
func?pkcs7Padding(data?[]byte,?blockSize?int)?[]byte?{
?padding?:=?blockSize?-?len(data)%blockSize
?padText?:=?bytes.Repeat([]byte{byte(padding)},?padding)
?return?append(data,?padText...)
}
func?pkcs7UnPadding(data?[]byte)?([]byte,?error)?{
?length?:=?len(data)
?if?length?==?0?{
??return?nil,?errors.New("Sorry,?the?encryption?string?is?wrong.")
?}
?unPadding?:=?int(data[length-1])
?return?data[:(length?-?unPadding)],?nil
}
func?AesEncrypt(data?[]byte,?key?[]byte)?([]byte,?error)?{
?block,?err?:=?aes.NewCipher(key)
?if?err?!=?nil?{
??return?nil,?err
?}
?blockSize?:=?block.BlockSize()
?encryptBytes?:=?pkcs7Padding(data,?blockSize)
?crypted?:=?make([]byte,?len(encryptBytes))
?blockMode?:=?cipher.NewCBCEncrypter(block,?key[:blockSize])
?blockMode.CryptBlocks(crypted,?encryptBytes)
?return?crypted,?nil
}
func?AesDecrypt(data?[]byte,?key?[]byte)?([]byte,?error)?{
?block,?err?:=?aes.NewCipher(key)
?if?err?!=?nil?{
??return?nil,?err
?}
?blockSize?:=?block.BlockSize()
?blockMode?:=?cipher.NewCBCDecrypter(block,?key[:blockSize])
?crypted?:=?make([]byte,?len(data))
?blockMode.CryptBlocks(crypted,?data)
?crypted,?err?=?pkcs7UnPadding(crypted)
?if?err?!=?nil?{
??return?nil,?err
?}
?return?crypted,?nil
}
func?EncryptByAes(data?[]byte)?(string,?error)?{
?res,?err?:=?AesEncrypt(data,?EncKey)
?if?err?!=?nil?{
??return?"",?err
?}
?return?base64.StdEncoding.EncodeToString(res),?nil
}
func?DecryptByAes(data?string)?([]byte,?error)?{
?dataByte,?err?:=?base64.StdEncoding.DecodeString(data)
?if?err?!=?nil?{
??return?nil,?err
?}
?return?AesDecrypt(dataByte,?EncKey)
}
const?help?=?`
Help?description?of?encryption?and?decryption?command?line?application
-h?--help?[Display?help]
-e?--encryption?Plaintext?string?encryption
-d?--decrypt?Ciphertext?string?decryption
Example:
1.?encryption?example:
passctl?-e?"your?plaintext?password"
2.?decryption?example:
passctl?-d?"Your?ciphertext?string"
`
func?main()?{
?args?:=?os.Args[1]
?if?args?==?"-h"?||?args?==?"--help"?{
??fmt.Print(help)
?}?else?if?args?==?"-e"?||?args?==?"--encryption"?{
??plaintext?:=?os.Args[2]
??p?:=?[]byte(plaintext)
??newp,?_?:=?EncryptByAes(p)
??fmt.Println(newp)
?}?else?if?args?==?"-d"?||?args?==?"--decrypt"?{
??ciphertext?:=?os.Args[2]
??a,?_?:=?DecryptByAes(ciphertext)
??fmt.Println(string(a))
?}?else?{
??fmt.Println("Invalid?option")
?}
}
編譯成二進(jìn)制后使用
#?編譯 [root@devhost?encryptionDecryption]#?go?build?-o?passctl?main.go #?查看幫助 [root@devhost?encryptionDecryption]#?./passctl?-h Help?description?of?encryption?and?decryption?command?line?application -h?--help?[Display?help] -e?--encryption?Plaintext?string?encryption -d?--decrypt?Ciphertext?string?decryption Example: 1.?encryption?example: passctl?-e?"your?plaintext?password" 2.?decryption?example: passctl?-d?"Your?ciphertext?string" #?加密 [root@devhost?encryptionDecryption]#?./passctl?-e?abc123456 nGi3ls+2yghdv7o8Ly2Z+A== #?解密 [root@devhost?encryptionDecryption]#?./passctl?-d?nGi3ls+2yghdv7o8Ly2Z+A== abc123456 [root@devhost?encryptionDecryption]#?
到此這篇關(guān)于Go語言實(shí)現(xiàn)AES加密并編寫一個(gè)命令行應(yīng)用程序的文章就介紹到這了,更多相關(guān)Go語言AES加密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語言中函數(shù)可變參數(shù)(Variadic Parameter)詳解
在Python中,在函數(shù)參數(shù)不確定數(shù)量的情況下,可以動(dòng)態(tài)在函數(shù)內(nèi)獲取參數(shù)。在Go語言中,也有類似的實(shí)現(xiàn)方式,本文就來為大家詳細(xì)講解一下2022-07-07
Go?語言簡單實(shí)現(xiàn)Vigenere加密算法
這篇文章主要介紹了Go語言簡單實(shí)現(xiàn)Vigenere加密算法,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-09-09
Kubernetes上使用Jaeger分布式追蹤基礎(chǔ)設(shè)施詳解
這篇文章主要為大家介紹了Kubernetes上使用Jaeger分布式追蹤基礎(chǔ)設(shè)施詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Go項(xiàng)目編寫Makefile規(guī)則文件概述
這篇文章主要為大家介紹了Go項(xiàng)目編寫Makefile文件規(guī)則概述,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04

