Hash算法
md5
package main
import (
"crypto/md5"
"fmt"
)
func main() {
hash := md5.New()
hash.Write([]byte("abc"))
fmt.Printf("hash:%x\n", hash.Sum(nil)) //hash:900150983cd24fb0d6963f7d28e17f72
}
SHA256
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
hash := sha256.New()
hash.Write([]byte("abc"))
fmt.Printf("hash:%x\n", hash.Sum(nil)) //hash:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
}
SHA512
package main
import (
"crypto/sha512"
"fmt"
)
func main() {
hash := sha512.New()
hash.Write([]byte("abc"))
fmt.Printf("hash:%x\n", hash.Sum(nil)) //hash:hash:ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
}
hmac
hmac 依赖于其它hash算法,在hash算法的基础上引入了秘钥的概念,根据秘钥的不同,来生成不同的hash结果
package main
import (
"crypto/hmac"
"crypto/md5"
"fmt"
)
func main() {
example := []byte("abc")
hash := hmac.New(md5.New, []byte("ak47"))
hash.Write(example)
hash2 := md5.New()
hash2.Write(example)
if fmt.Sprintf("%x", hash.Sum(nil)) != fmt.Sprintf("%x", hash2.Sum(nil)) {
fmt.Println("hmac != hash") //hmac != hash
}
}
对称加密算法
DES
要求key为8字节,加解密数据也为8字节
package main
import (
"crypto/des"
"fmt"
)
func main() {
cipher, err := des.NewCipher([]byte("12345678"))
if err != nil {
panic(err)
}
EncryptResult := make([]byte, 8)
DecryptResult := make([]byte, 8)
plain := []byte("87654321")
cipher.Encrypt(EncryptResult, plain)
cipher.Decrypt(DecryptResult, EncryptResult)
fmt.Println(plain) //[56 55 54 53 52 51 50 49]
fmt.Println(EncryptResult) //[56 84 48 40 155 117 148 36]
fmt.Println(DecryptResult) //[56 55 54 53 52 51 50 49]
}
3DES
在DES的基础上,总共进行三次DES加解密,提升DES的安全性,增加暴力破解难度,由于进行三次加解密,所以需要提供24字节的key
package main
import (
"crypto/des"
"fmt"
)
func main() {
cipher, err := des.NewTripleDESCipher([]byte("123456781994011319960626"))
if err != nil {
panic(err)
}
EncryptResult := make([]byte, 8)
DecryptResult := make([]byte, 8)
plain := []byte("87654321")
cipher.Encrypt(EncryptResult, plain)
cipher.Decrypt(DecryptResult, EncryptResult)
fmt.Println(plain) //[56 55 54 53 52 51 50 49]
fmt.Println(EncryptResult) //[48 100 4 163 34 141 1 112]
fmt.Println(DecryptResult) //[56 55 54 53 52 51 50 49]
}
AES
AES需要 (16,24,32)字节的key和16字节的data
package main
import (
"crypto/aes"
"fmt"
)
func main() {
var (
encryptResult = make([]byte, 16)
key = []byte("1234567812345678")
source = []byte("1111222233334444")
)
cipher, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
cipher.Encrypt(encryptResult, source)
fmt.Println(encryptResult) //[50 50 164 142 39 30 55 128 22 114 255 134 72 22 134 162]
}
如果加密数据超过16位,那么就要使迭代模式了,下面代码展示了使用CBC模式对32字节的数据进行加解密
package main
import (
"crypto/aes"
"crypto/cipher"
"fmt"
)
func main() {
var (
key = []byte("1234567812345678")
source = []byte("11112222333344441111222233334444")
encryptResult = make([]byte, 32)
decryptResult = make([]byte, 32)
iv = make([]byte, 16)
)
cipherBlock, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
encrypter := cipher.NewCBCEncrypter(cipherBlock, iv)
encrypter.CryptBlocks(encryptResult, source)
decrypter := cipher.NewCBCDecrypter(cipherBlock, iv)
decrypter.CryptBlocks(decryptResult, encryptResult)
fmt.Println(encryptResult) //[50 50 164 142 39 30 55 128 22 114 255 134 72 22 134 162]
fmt.Println(decryptResult) //[49 49 49 49 50 50 50 50 51 51 51 51 52 52 52 52 49 49 49 49 50 50 50 50 51 51 5 1 51 52 52 52 52]
fmt.Println(source) //[49 49 49 49 50 50 50 50 51 51 51 51 52 52 52 52 49 49 49 49 50 50 50 50 51 51 5 1 51 52 52 52 52]
}
通常我们再迭代模式中,会将每16字节分成一个块,如果某个块不足16字节,会对其进行填充
填充方法:
package main
import (
"bytes"
"fmt"
)
func Pkcs5Padding(source []byte) []byte {
padding := 16 - len(source)%16
paddingBytes := bytes.Repeat([]byte{byte(padding)}, padding)
return append(source, paddingBytes...)
}
func main() {
padding := Pkcs5Padding([]byte("abc"))
fmt.Println(padding)
}
移除填充:
package main
import (
"bytes"
"fmt"
)
func Pkcs5Padding(source []byte) []byte {
padding := 16 - len(source)%16
paddingBytes := bytes.Repeat([]byte{byte(padding)}, padding)
return append(source, paddingBytes...)
}
func UnPkcs5Padding(source []byte) []byte {
unPadding := int(source[len(source)-1])
return source[:(len(source) - unPadding)]
}
func main() {
padding := Pkcs5Padding([]byte("abc"))
fmt.Println(padding) //[97 98 99 13 13 13 13 13 13 13 13 13 13 13 13 13]
unPadding := UnPkcs5Padding(padding)
fmt.Println(unPadding) //[97 98 99]
}
非对称加密
非对称加密生成两个不同的key(公钥,私钥)
公钥加密的私钥可以解,私钥加密的公钥可以解
生成私钥:
openssl genrsa -out private.pem 2048
生成对应公钥:
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
签名验签
私钥签名:
func RsaSign(plainText []byte) []byte {
open, err := os.Open("private.pem")
if err != nil {
panic(err)
}
fileInfo, _ := open.Stat()
data := make([]byte, fileInfo.Size())
_, err = open.Read(data)
if err != nil {
panic(err)
}
p, _ := pem.Decode(data)
key, err := x509.ParsePKCS1PrivateKey(p.Bytes)
if err != nil {
panic(err)
}
hashed := sha256.Sum256(plainText)
v15, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, hashed[:])
if err != nil {
panic(err)
}
return v15
}
func main() {
fmt.Println(RsaSign([]byte("abc")))
}
公钥验签:
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
)
func RsaSign(plainText []byte) []byte {
open, err := os.Open("private.pem")
if err != nil {
panic(err)
}
fileInfo, _ := open.Stat()
data := make([]byte, fileInfo.Size())
_, err = open.Read(data)
if err != nil {
panic(err)
}
p, _ := pem.Decode(data)
key, err := x509.ParsePKCS1PrivateKey(p.Bytes)
if err != nil {
panic(err)
}
hashed := sha256.Sum256(plainText)
v15, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, hashed[:])
if err != nil {
panic(err)
}
return v15
}
func VerifySign(plainText []byte, signature []byte) error {
open, err := os.Open("public.pem")
if err != nil {
panic(err)
}
fileInfo, _ := open.Stat()
data := make([]byte, fileInfo.Size())
_, err = open.Read(data)
if err != nil {
panic(err)
}
p, _ := pem.Decode(data)
key, err := x509.ParsePKIXPublicKey(p.Bytes)
if err != nil {
panic(err)
}
hashed := sha256.Sum256(plainText)
return rsa.VerifyPKCS1v15(key.(*rsa.PublicKey), crypto.SHA256, hashed[:], signature)
}
func main() {
signature := RsaSign([]byte("abc"))
if err := VerifySign([]byte("abc"), signature); err != nil {
fmt.Println("验签失败")
return
}
fmt.Println("验签通过")
}
加解密
这里使用公钥加密数据,私钥解密数据
公钥加密:
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
)
func Encrypt(plainText []byte) ([]byte, error) {
open, err := os.Open("public.pem")
if err != nil {
panic(err)
}
fileInfo, _ := open.Stat()
data := make([]byte, fileInfo.Size())
_, err = open.Read(data)
if err != nil {
return nil, err
}
p, _ := pem.Decode(data)
key, err := x509.ParsePKIXPublicKey(p.Bytes)
if err != nil {
return nil, err
}
return rsa.EncryptPKCS1v15(rand.Reader, key.(*rsa.PublicKey), plainText)
}
func main() {
fmt.Println(Encrypt([]byte("abc")))
}
私钥解密:文章来源:https://www.toymoban.com/news/detail-724056.html
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
)
func Decrypt(plainText []byte) ([]byte, error) {
open, err := os.Open("private.pem")
if err != nil {
panic(err)
}
fileInfo, _ := open.Stat()
data := make([]byte, fileInfo.Size())
_, err = open.Read(data)
if err != nil {
return nil, err
}
p, _ := pem.Decode(data)
key, err := x509.ParsePKCS1PrivateKey(p.Bytes)
if err != nil {
return nil,err
}
return rsa.DecryptPKCS1v15(rand.Reader, key, plainText)
}
func Encrypt(plainText []byte) ([]byte, error) {
open, err := os.Open("public.pem")
if err != nil {
panic(err)
}
fileInfo, _ := open.Stat()
data := make([]byte, fileInfo.Size())
_, err = open.Read(data)
if err != nil {
return nil, err
}
p, _ := pem.Decode(data)
key, err := x509.ParsePKIXPublicKey(p.Bytes)
if err != nil {
return nil, err
}
return rsa.EncryptPKCS1v15(rand.Reader, key.(*rsa.PublicKey), plainText)
}
func main() {
encryptData, _ := Encrypt([]byte("abc"))
decryptData, _ := Decrypt(encryptData)
fmt.Println(string(decryptData))
}
文章来源地址https://www.toymoban.com/news/detail-724056.html
到了这里,关于Go 常用加密算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!