目录
- GoLang加密方法
- GoLang三类加密算法
- 哈希算法
- 对称加密
- 非对称加密
- 总结
GoLang加密方法
以下Golang代码的加密结果与Java语言结果一致,需要注意结果大小写问题。
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验证
func MD5Str(src string) string {
h := md5.New()
h.Write([]byte(src)) // 需要加密的字符串为
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}
// hmacsha256验证
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验证
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验证
func SHA256Str(src string) string {
h := sha256.New()
h.Write([]byte(src)) // 需要加密的字符串为
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
return hex.EncodeToString(h.Sum(nil))
}
// sha512验证
func SHA512Str(src string) string {
h := sha512.New()
h.Write([]byte(src)) // 需要加密的字符串为
// fmt.Printf("%s\n", hex.EncodeToString(h.Sum(nil))) // 输出加密结果
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)
}
调用
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函数应用:
消息认证是用来验证消息完整性的一种机制或服务,消息认证确认收到的数据确实和发送时的一样(即防篡改),并且还要确保发送方的身份是真实有效的的(即防冒充)。
也就是说哈希函数只是确定信息来自生产者,只有验证功能,不可用于信息传输,因为没有解密算法。
表格中算法的golang实现
import 包 :
import (
"hash/crc32"
"hash/crc64"
"hash/adler32"
"crypto/sha512"
"crypto/sha256"
"crypto/sha1"
"crypto/md5"
"encoding/hex"
)
老师说用于验证的哈希函数,一般不单个用,定义加密接口的时候,定义一个[]string用于存放组合的哈希函数的名字,如:[]string{“md5",“crc64”,“sha256”.“sha256”······}
type AllHash struct {
Alog []string
}
绑定方法根据哈希名字将数据哈希化,这些函数被Go标准库给敷衍了,解释在十个字以内,要不就没有,我giao
对于md5,sha1,sha256,sha512步骤一样,
我猜:
(以md5为例)
1.New一个的对象,相当于申请了一块buf:myhash:=md5.New()
2.向这个buf中写入字节类型的数据:myhash.Write([]byte(laststr))
3.进行相应的哈希运算:bs:=myhash.Sum(nil),我用反射查看bs的类型是[]uint8.
4.最终数据以16进制输出 :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)
}
}
对称加密
对称加密,消息发送端要先有一个密钥,然后执行加密算法,获得加密数据;接受端要事先获得发送者的密钥,用密钥进行解密。
对称加密适合对大量数据进行加密,由于传输密钥并不安全,真正使用时,对数据进行对称加密,对密钥进行非对称加密。
DES加密步骤:
- 1.确定密钥位数,不够的补零,超了截。这里假设密钥是24位
- 2.调用第三方库goEncrypt的TripleDesEncrypt,利用密钥进行加密
- 3.返回加密数据。
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.确定密钥位数,不够的补零,超了截。这里假设密钥是24位
- 2.调用第三方库goEncrypt的TripleDesDecrypt,利用密钥进行解密
- 3.返回解密数据
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
}
非对称加密
私钥加密,公钥解密;公钥加密,私钥解密,称之为非对称加密。
双方进行信息传递,双方都需要创建公钥和私钥,如果己方用私钥加密,就要把公钥传给对方,对方用公钥解密。
下面是ECCgolang实现:
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
}