Golang中常见加密算法的总结

目录
  • 1.md5 加密——不可逆
  • 2.hmacsha 加密——不可逆
    • hmac-md5加密
    • hamacsha1 加密
    • hamacsha 256 加密
    • hmacsha512加密
    • hamasha 调用
  • 3.Sha 加密——不可逆
    • sha1
    • sha256
    • sha512
    • sha调用
  • 4.base 加密 解密
    • 加密
    • 解密
    • base64 调用
  • 5.AES 加密
    • CBC方式
    • ECB方式
    • CFB 方式
  • 6.RSA加密
    • RSA加密
    • RSA分段加密
  • 7.DES加密
    • 内置库完成
    • 使用第三方库
  • 8.3DES加密算法

如果想直接使用我下列的库

可以直接go get 我的github

go get -u github.com/hybpjx/InverseAlgorithm

1.md5 加密——不可逆

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

import (
    "crypto/md5"
    "encoding/hex"
    "fmt"
)

第一种

// MD5Str 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))
}

第二种

// MD5Str2 md5验证
func MD5Str2(src string) string {
    return fmt.Sprintf("%x", md5.Sum([]byte(src)))
}

2.hmacsha 加密——不可逆

HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,它通过一个标准算法,在计算哈希的过程中,把key混入计算过程中。

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

hmac-md5加密

//key随意设置 data 要加密数据

func Hmac(key, data string) string {
    // 创建对应的md5哈希加密算法
    hash:= hmac.New(md5.New, []byte(key)) 

    hash.Write([]byte(data))

    return hex.EncodeToString(hash.Sum([]byte("")))

}

hamacsha1 加密

// HmacSha1 hmacSha1加密 key随意设置 data 要加密数据
func HmacSha1(src, key string) string {
    m := hmac.New(sha1.New, []byte(key))
    m.Write([]byte(src))
    return hex.EncodeToString(m.Sum(nil))
}

hamacsha 256 加密

// HmacSHA256 hmacSha256验证  key随意设置 data 要加密数据
func HmacSHA256(key, src string) string {
    m := hmac.New(sha256.New, []byte(key))
    m.Write([]byte(src))
    return hex.EncodeToString(m.Sum(nil))
}

hmacsha512加密

// HmacSHA512 hmacSha512验证
func HmacSHA512(key, src string) string {
    m := hmac.New(sha512.New, []byte(key))
    m.Write([]byte(src))
    return hex.EncodeToString(m.Sum(nil))
}

hamasha 调用

package main

import (
    "crypto/hmac"
    "crypto/md5"
    "crypto/sha1"
    "crypto/sha256"
    "crypto/sha512"
    "encoding/hex"
    "fmt"
)

// Hmac hmac验证 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("")))

}

// HmacSHA256 hmacSha256加密  key随意设置 data 要加密数据
func HmacSHA256(key, src string) string {
    m := hmac.New(sha256.New, []byte(key))
    m.Write([]byte(src))
    return hex.EncodeToString(m.Sum(nil))
}

// HmacSHA512 hmacSha512加密 key随意设置 data 要加密数据
func HmacSHA512(key, src string) string {
    m := hmac.New(sha512.New, []byte(key))
    m.Write([]byte(src))
    return hex.EncodeToString(m.Sum(nil))
}

// HmacSha1 hmacSha1加密 key随意设置 data 要加密数据
func HmacSha1(src, key string) string {
    m := hmac.New(sha1.New, []byte(key))
    m.Write([]byte(src))
    return hex.EncodeToString(m.Sum(nil))
}

// SHA256Str 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))
}

func main() {
    hmac_ := Hmac("hybpjx", "始識")
    hamcsha1 := HmacSha1("hybpjx", "始識")
    hamcsha256 := HmacSHA256("hybpjx", "始識")
    hamacsha512 := HmacSHA512("hybpjx", "始識")
    fmt.Println(hmac_)
    fmt.Println(hamcsha1)
    fmt.Println(hamcsha256)
    fmt.Println(hamacsha512)
}

结果

d8801f70df7891764116e1ac003f7189
60d68e01c8a86f3b87e4e147e9f0fadce2a69661
b3f8ddf991288036864761a55046877adfe4f78ec9a89bb63932af92689b139f
b9b1fca0fe91522482ee1b2161e57d67482af6ef371614365b918c31ce774f9126ed627e378a063145f404ff2de7bd84f8e4798c385662ef4749e58e9209ca63

3.Sha 加密——不可逆

sha1

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

func Sha1(data string) string {
    sha1_ := sha1.New()
    sha1_.Write([]byte(data))
    return hex.EncodeToString(sha1_.Sum([]byte("")))
}

sha256

SHA256算法使用的哈希值长度是256位。这是一个抽象类。此类的唯一实现是SHA256Managed。

// SHA256 sha256加密
func SHA256(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

SHA (Secure Hash Algorithm,译作安全散列算法) 是美国国家安全局 (NSA) 设计,美国国家标准与技术研究院 (NIST) 发布的一系列密码散列函数。

// SHA512 sha512加密
func SHA512(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))
}

sha调用

package main

import (
    "crypto/sha1"
    "crypto/sha256"
    "crypto/sha512"
    "encoding/hex"
    "fmt"
)

func Sha1(data string) string {
    sha1_ := sha1.New()
    sha1_.Write([]byte(data))
    return hex.EncodeToString(sha1_.Sum([]byte("")))
}

// SHA256 sha256加密
func SHA256(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 sha512加密
func SHA512(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))
}

func main() {
    _sha1 := Sha1("始識")
    _sha256 := SHA256("始識")
    _sha512 := SHA512("始識")
    fmt.Println(_sha1)
    fmt.Println(_sha256)
    fmt.Println(_sha512)
}

结果

7bac01cc58a26f3cb280b0466794a89441279946
6ef99e6d3fe34a46afcdc438435728fe95ffdab18e389ddd31609edd6729b11d
0c04e9b79f488646d0eac6f65468248507939d643cc92709b14eb0d18d8f13db509ed5ccd3312d6c234408185a4611a42525dce9e8d32255640f56a2f836635a

4.base 加密 解密

加密

// BASE64StdEncode base编码
func BASE64StdEncode(src string) string {
    return base64.StdEncoding.EncodeToString([]byte(src))
}

解密

// BASE64StdDecode base解码
func BASE64StdDecode(src string) string {
    a, err := base64.StdEncoding.DecodeString(src)
    if err != nil {
        _ = fmt.Errorf("解密失败,%v\n", err)
    }
    return string(a)
}

base64 调用

package main

import (
    "encoding/base64"
    "fmt"
)

// BASE64StdEncode base编码
func BASE64StdEncode(src string) string {
    return base64.StdEncoding.EncodeToString([]byte(src))
}

// BASE64StdDecode base解码
func BASE64StdDecode(src string) string {
    a, err := base64.StdEncoding.DecodeString(src)
    if err != nil {
        _ = fmt.Errorf("解密失败,%v\n", err)
    }
    return string(a)
}

func main() {
    encodeBase64 := BASE64StdEncode("hybpjx")
    decodeBase64 := BASE64StdDecode(encodeBase64)
    fmt.Println(encodeBase64)
    fmt.Println(decodeBase64)
}

结果

aHlicGp4
hybpjx

5.AES 加密

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

由于加密和解密的秘钥是相同的,所以AES为对称加密

package main

import (
    "bytes"
    "crypto/aes"
    "crypto/cipher"
    "encoding/base64"
    "fmt"
)

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)]
}

//AES加密
func AesEncrypt(origData, key []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    blockSize := block.BlockSize()
    origData = PKCS7Padding(origData, blockSize)
    blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
    crypted := make([]byte, len(origData))
    blockMode.CryptBlocks(crypted, origData)
    return crypted, nil
}

//AES解密
func AesDecrypt(crypted, key []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    blockSize := block.BlockSize()
    blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
    origData := make([]byte, len(crypted))
    blockMode.CryptBlocks(origData, crypted)
    origData = PKCS7UnPadding(origData)
    return origData, nil
}

func main() {
    text := "今晚打老虎"
    AesKey := []byte("0f90023fc9ae101e") //秘钥长度为16的倍数
    fmt.Printf("明文: %s\n秘钥: %s\n", text, string(AesKey))
    encrypted, err := AesEncrypt([]byte(text), AesKey)
    if err != nil {
        panic(err)
    }
    fmt.Printf("加密后: %s\n", base64.StdEncoding.EncodeToString(encrypted))
    origin, err := AesDecrypt(encrypted, AesKey)
    if err != nil {
        panic(err)
    }
    fmt.Printf("解密后明文: %s\n", string(origin))
}

CBC方式

package main

import (
    "bytes"
    "crypto/aes"
    "crypto/cipher"
    "encoding/base64"
    "encoding/hex"
    "log"
)

func AesEncryptCBC(origData []byte, key []byte) (encrypted []byte) {
    // 分组秘钥
    // NewCipher该函数限制了输入k的长度必须为16, 24或者32
    block, _ := aes.NewCipher(key)
    blockSize := block.BlockSize()                              // 获取秘钥块的长度
    origData = pkcs5Padding(origData, blockSize)                // 补全码
    blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 加密模式
    encrypted = make([]byte, len(origData))                     // 创建数组
    blockMode.CryptBlocks(encrypted, origData)                  // 加密
    return encrypted
}
func AesDecryptCBC(encrypted []byte, key []byte) (decrypted []byte) {
    block, _ := aes.NewCipher(key)                              // 分组秘钥
    blockSize := block.BlockSize()                              // 获取秘钥块的长度
    blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // 加密模式
    decrypted = make([]byte, len(encrypted))                    // 创建数组
    blockMode.CryptBlocks(decrypted, encrypted)                 // 解密
    decrypted = pkcs5UnPadding(decrypted)                       // 去除补全码
    return 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 pkcs5UnPadding(origData []byte) []byte {
    length := len(origData)
    unpadding := int(origData[length-1])
    return origData[:(length - unpadding)]
}
func main() {
    origData := []byte("460154561234") // 待加密的数据
    key := []byte("9876787656785679")  // 加密的密钥
    log.Println("原文:", string(origData))

    log.Println("------------------ CBC模式 --------------------")
    encrypted := AesEncryptCBC(origData, key)
    log.Println("密文(hex):", hex.EncodeToString(encrypted))
    log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))
    decrypted := AesDecryptCBC(encrypted, key)
    log.Println("解密结果:", string(decrypted))
}

ECB方式

package main

import (
    "crypto/aes"
    "encoding/base64"
    "encoding/hex"
    "log"
)

func AesEncryptECB(origData []byte, key []byte) (encrypted []byte) {
    cipher, _ := aes.NewCipher(generateKey(key))
    length := (len(origData) + aes.BlockSize) / aes.BlockSize
    plain := make([]byte, length*aes.BlockSize)
    copy(plain, origData)
    pad := byte(len(plain) - len(origData))
    for i := len(origData); i < len(plain); i++ {
        plain[i] = pad
    }
    encrypted = make([]byte, len(plain))
    // 分组分块加密
    for bs, be := 0, cipher.BlockSize(); bs <= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
        cipher.Encrypt(encrypted[bs:be], plain[bs:be])
    }

    return encrypted
}
func AesDecryptECB(encrypted []byte, 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.Decrypt(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() {
    origData := []byte("460154561234") // 待加密的数据
    key := []byte("9876787656785679")  // 加密的密钥
    log.Println("原文:", string(origData))

    log.Println("------------------ ECB模式 --------------------")
    encrypted := AesEncryptECB(origData, key)
    log.Println("密文(hex):", hex.EncodeToString(encrypted))
    log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))
    decrypted := AesDecryptECB(encrypted, key)
    log.Println("解密结果:", string(decrypted))
}

CFB 方式

package main

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
    "encoding/base64"
    "encoding/hex"
    "io"
    "log"
)

func AesEncryptCFB(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.XORKeyStream(encrypted, encrypted)
    return encrypted
}
func main() {
    origData := []byte("460154561234") // 待加密的数据
    key := []byte("9876787656785679")  // 加密的密钥
    log.Println("原文:", string(origData))

    log.Println("------------------ CFB模式 --------------------")
    encrypted := AesEncryptCFB(origData, key)
    log.Println("密文(hex):", hex.EncodeToString(encrypted))
    log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))
    decrypted := AesDecryptCFB(encrypted, key)
    log.Println("解密结果:", string(decrypted))
}

6.RSA加密

RSA是一种基于公钥密码体制的优秀加密算法,1978年由美国(MIT)的李维斯特(Rivest)、沙米尔(Shamir)、艾德曼(Adleman)提的。

RSA算法是一种分组密码体制算法,它的保密强度是建立在具有大素数因子的合数其因子分解是困难的(基于大数分解的难度)。公钥和私钥是一对大素数的函数,从一个公钥和密文中恢复出明文的难度等价于分解两个大素数之积。

RSA得到了世界上的最广泛的应用,ISO在1992年颁布的国际标准X.509中,将RSA算法正式纳入国际标准。

RSA加密

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "os"
)

// GenerateRSAKey 生成RSA私钥和公钥,保存到文件中
func GenerateRSAKey(bits int){
    //GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
    //Reader是一个全局、共享的密码用强随机数生成器
    privateKey, err := rsa.GenerateKey(rand.Reader, bits)
    if err!=nil{
        panic(err)
    }
    //保存私钥
    //通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
    // X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey) // PKCS1 和 9 是不一致的
    X509PrivateKey,err := x509.MarshalPKCS8PrivateKey(privateKey)
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(0)
    }
    //使用pem格式对x509输出的内容进行编码
    //创建文件保存私钥
    privateFile, err := os.Create("private.pem")
    if err!=nil{
        panic(err)
    }
    defer privateFile.Close()
    //构建一个pem.Block结构体对象
    privateBlock:= pem.Block{Type: "PRIVATE KEY",Bytes:X509PrivateKey}
    //将数据保存到文件
    pem.Encode(privateFile,&privateBlock)
    //保存公钥
    //获取公钥的数据
    publicKey:=privateKey.PublicKey
    //X509对公钥编码
    X509PublicKey,err:=x509.MarshalPKIXPublicKey(&publicKey)
    if err!=nil{
        panic(err)
    }
    //pem格式编码
    //创建用于保存公钥的文件
    publicFile, err := os.Create("public.pem")
    if err!=nil{
        panic(err)
    }
    defer publicFile.Close()
    //创建一个pem.Block结构体对象
    publicBlock:= pem.Block{Type: "Public Key",Bytes:X509PublicKey}
    //保存到文件
    pem.Encode(publicFile,&publicBlock)
}

// RsaEncrypt RSA加密
func RsaEncrypt(plainText []byte,path string)[]byte{
    //打开文件
    file,err:=os.Open(path)
    if err!=nil{
        panic(err)
    }
    defer file.Close()
    //读取文件的内容
    info, _ := file.Stat()
    buf:=make([]byte,info.Size())
    file.Read(buf)
    //pem解码
    block, _ := pem.Decode(buf)
    //x509解码
    publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err!=nil{
        panic(err)
    }
    //类型断言
    publicKey:=publicKeyInterface.(*rsa.PublicKey)
    //对明文进行加密
    cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
    if err!=nil{
        panic(err)
    }
    //返回密文
    return cipherText
}

// RsaDecrypt RSA解密
func RsaDecrypt(cipherText []byte,path string) []byte{
    //打开文件
    file,err:=os.Open(path)
    if err!=nil{
        panic(err)
    }
    defer file.Close()
    //获取文件内容
    info, _ := file.Stat()
    buf:=make([]byte,info.Size())
    file.Read(buf)
    //pem解码
    block, _ := pem.Decode(buf)
    //X509解码
    privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
    if err!=nil{
        fmt.Println(err.Error())
        os.Exit(0)
    }
    //对密文进行解密
    plainText,_:=rsa.DecryptPKCS1v15(rand.Reader,privateKey.(*rsa.PrivateKey),cipherText)
    //返回明文
    return plainText
}

func main(){
    // RSA/ECB/PKCS1Padding
    // RSA是算法,ECB是分块模式,PKCS1Padding是填充模式

    // pkcs1私钥生成openssl genrsa -out pkcs1.pem 1024
    // pkcs1转pkcs8私钥 :openssl pkcs8 -in pkcs8.pem -nocrypt -out pkcs1.pem

    // pkcs1 BEGIN RSA PRIVATE KEY
    // pkcs8 BEGIN PRIVATE KEY

    GenerateRSAKey(1024)
    publicPath := "public_key.pem"
    privatePath := "private_key.pem"

    publicPath = "public.pem"
    privatePath = "private.pem"

    txt := []byte("hello")
    encrptTxt := RsaEncrypt(txt,publicPath)
    decrptCode := RsaDecrypt(encrptTxt,privatePath)
    fmt.Println(string(decrptCode))

}

RSA分段加密

package main

import (
    "bytes"
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "fmt"
    "log"
    "os"
)

func main() {
    GenerateRSAKey(2048)
    publicPath := "public.pem"
    privatePath := "private.pem"
    var a = []byte("hello")
    encrptTxt, err := RsaEncryptBlock(a, publicPath)
    if err != nil {
        fmt.Println(err.Error())
    }
    encodeString := base64.StdEncoding.EncodeToString(encrptTxt)
    decodeByte, err := base64.StdEncoding.DecodeString(encodeString)
    if err != nil {
        panic(err)
    }
    //生成RSA私钥和公钥,保存到文件中
    decrptCode := RSA_Decrypts(decodeByte, privatePath)
    fmt.Println(string(decrptCode))

}

func GenerateRSAKey(bits int) {
    //GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
    //Reader是一个全局、共享的密码用强随机数生成器
    privateKey, err := rsa.GenerateKey(rand.Reader, bits)
    if err != nil {
        panic(err)
    }
    //保存私钥
    //通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
    // X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey) // PKCS1 和 9 是不一致的
    X509PrivateKey, err := x509.MarshalPKCS8PrivateKey(privateKey)
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(0)
    }
    //使用pem格式对x509输出的内容进行编码
    //创建文件保存私钥
    privateFile, err := os.Create("private.pem")
    if err != nil {
        panic(err)
    }
    defer privateFile.Close()
    //构建一个pem.Block结构体对象
    privateBlock := pem.Block{Type: "PRIVATE KEY", Bytes: X509PrivateKey}
    //将数据保存到文件
    pem.Encode(privateFile, &privateBlock)
    //保存公钥
    //获取公钥的数据
    publicKey := privateKey.PublicKey
    //X509对公钥编码
    X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
    if err != nil {
        panic(err)
    }
    //pem格式编码
    //创建用于保存公钥的文件
    publicFile, err := os.Create("public.pem")
    if err != nil {
        panic(err)
    }
    defer publicFile.Close()
    //创建一个pem.Block结构体对象
    publicBlock := pem.Block{Type: "Public Key", Bytes: X509PublicKey}
    //保存到文件
    pem.Encode(publicFile, &publicBlock)
}

// RSA_Decrypts RSA解密支持分段解密
func RSA_Decrypts(cipherText []byte, path string) []byte {
    //打开文件
    var bytesDecrypt []byte
    file, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer file.Close()
    //获取文件内容
    info, _ := file.Stat()
    buf := make([]byte, info.Size())
    file.Read(buf)
    //pem解码
    block, _ := pem.Decode(buf)
    //X509解码
    privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(0)
    }
    p := privateKey.(*rsa.PrivateKey)
    keySize := p.Size()
    srcSize := len(cipherText)
    log.Println("密钥长度", keySize, "密文长度", srcSize)
    var offSet = 0
    var buffer = bytes.Buffer{}
    for offSet < srcSize {
        endIndex := offSet + keySize
        if endIndex > srcSize {
            endIndex = srcSize
        }
        bytesOnce, err := rsa.DecryptPKCS1v15(rand.Reader, p, cipherText[offSet:endIndex])
        if err != nil {
            return nil
        }
        buffer.Write(bytesOnce)
        offSet = endIndex
    }
    bytesDecrypt = buffer.Bytes()
    return bytesDecrypt
}

// RsaEncryptBlock 公钥加密-分段
func RsaEncryptBlock(src []byte, path string) (bytesEncrypt []byte, err error) {
    //打开文件
    file, err := os.Open(path)
    if err != nil {
        panic(err)
    }
    defer file.Close()
    //读取文件的内容
    info, _ := file.Stat()
    buf := make([]byte, info.Size())
    file.Read(buf)
    //pem解码
    block, _ := pem.Decode(buf)
    //x509解码
    publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
        panic(err)
    }
    //类型断言
    publicKey := publicKeyInterface.(*rsa.PublicKey)
    keySize, srcSize := publicKey.Size(), len(src)
    log.Println("密钥长度", keySize, "明文长度", srcSize)
    offSet, once := 0, keySize-11
    buffer := bytes.Buffer{}
    for offSet < srcSize {
        endIndex := offSet + once
        if endIndex > srcSize {
            endIndex = srcSize
        }
        // 加密一部分
        bytesOnce, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, src[offSet:endIndex])
        if err != nil {
            return nil, err
        }
        buffer.Write(bytesOnce)
        offSet = endIndex
    }
    bytesEncrypt = buffer.Bytes()
    return
}

7.DES加密

DES(Data Encryption)是1977年美国联邦信息处理标准(FIPS)中所采用的一种对称密码(FIPS46-3)。随着计算机的进步,DES已经能够被暴力破解,1997年的DES Challenge I 中用了96天破译密钥,1998年的DES Challenge II-1中用了41天,1998年的DES Challenge II-2中用了56小时,1999年的DES Challenge III 中只用了22小时15分钟。

DES是一种将64比特的明文加密成64比特的密文的对称密码算法,它的密钥的长度是56比特。尽管从规格上来说,DES的密钥长度是64比特,但由于每隔7比特会设置一个用于错误检查的比特,因此实质上其密钥长度是56比特。

DES 是以64比特的明文(比特序列)为一个单位来进行加密的,这个64比特的单位称为分组 ,一般来说,以分组为单位进行处理的密码算法称为分组密码,DES就是分组密码的一种。

DES每次只能加密64比特的数据,如果要加密的明文比较长,就需要对DES加密进行迭代(反复),而迭代的具体方式就称为模式。

DES 内部实现理论:在 des 中各个步骤称为轮,整个加密过程进行16轮循环。

内置库完成

加密模式采用ECB、填充方式采用pkcs5padding、密码使用"12345678",输出时经hex编码。自己可以通过一些在线测试工具进行测试,看结果是否一致。

package main

import (
    "bytes"
    "crypto/cipher"
    "crypto/des"
    "encoding/hex"
    "fmt"
)

func main() {
    data := []byte("hello world")
    key := []byte("12345678")
    iv := []byte("43218765")

    result, err := DesCBCEncrypt(data, key, iv)
    if err != nil {
        fmt.Println(err)
    }
    b := hex.EncodeToString(result)
    fmt.Println(b)
}

func DesCBCEncrypt(data, key, iv []byte) ([]byte, error) {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil, err
    }

    data = pkcs5Padding(data, block.BlockSize())
    cryptText := make([]byte, len(data))

    blockMode := cipher.NewCBCEncrypter(block, iv)
    blockMode.CryptBlocks(cryptText, data)
    return cryptText, nil
}

func pkcs5Padding(cipherText []byte, blockSize int) []byte {
    padding := blockSize - len(cipherText)%blockSize
    padText := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(cipherText, padText...)
}

使用第三方库

package main

import (
    "fmt"
    "github.com/marspere/goencrypt"
)

func main() {
    // key为12345678
    // iv为空
    // 采用ECB分组模式
    // 采用pkcs5padding填充模式
    // 输出结果使用base64进行加密
    cipher := goencrypt.NewDESCipher([]byte("12345678"), []byte(""), goencrypt.ECBMode, goencrypt.Pkcs7, goencrypt.PrintBase64)
    cipherText, err := cipher.DESEncrypt([]byte("hello world"))
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(cipherText)
}

8.3DES加密算法

3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。
由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

还有一个库 非常NB

ECB模式下的3DES算法加解密信息,golang默认只提供CBC模式

这边有golang的加密库,非常厉害

https://github.com/forgoer/openssl

安装:

go get github.com/thinkoner/openssl

代码如下:

package main

import (
    "encoding/base64"
    "encoding/hex"
    "fmt"
    "github.com/forgoer/openssl"
)

func main() {

    //定义密钥,必须是24byte
    key := []byte("123456789012345678901234")
    fmt.Println("密钥:", key, hex.EncodeToString(key))

    //定义明文
    src := []byte("0102030109000000030000000F8898E37A7F8F3D742006111118080000FACE05")

    //3DES-ECB加密
    encodeData, _ := openssl.Des3ECBEncrypt(src, key, openssl.ZEROS_PADDING)
    encryptBaseData := base64.StdEncoding.EncodeToString(encodeData)

    fmt.Println("加密后Base64:", encryptBaseData)
    fmt.Println("加密后Hex:", hex.EncodeToString(encodeData))

    //3DES-ECB解密
    decodeBaseData, _ := base64.StdEncoding.DecodeString(encryptBaseData)
    decodeData, _ := openssl.Des3ECBDecrypt(decodeBaseData, key, openssl.ZEROS_PADDING)

    fmt.Println("解密后:", hex.EncodeToString(decodeData))
}

包括 Des的加密解密

以下只举一个例子

srcData := "L0j+JvbeVM0svSpjIwXdE7yTu78wiEszCmW8rwjXY3vrx2nEaUeJ/Rw/c/IRdlxIH+/ro4pykx6ESOkGU1YwM8ddEuuoTg5uPsqQ9/SuNds="
key := []byte("Ctpsp@884*"[:8])
//3DES-ECB解密
decodeBaseData, _ := base64.StdEncoding.DecodeString(srcData)
decodeData, _ := openssl.DesECBDecrypt(decodeBaseData, key, openssl.PKCS5_PADDING)
fmt.Println("解密后:", string(decodeData))

源文件: https://github.com/hybpjx/InverseAlgorithm

以上就是Golang中常见加密算法的总结的详细内容,更多关于Golang加密的资料请关注我们其它相关文章!

(0)

相关推荐

  • Go实现基于RSA加密算法的接口鉴权

    基于 RSA 加密算法的接口鉴权方案 假设接口调用者是客户端,接口提供方是服务端,则此方案存在以下规则: 客户端需要使用 RSA 算法(1024 位长度的私钥)生成公私钥,并将公钥下发给服务端: 客户端使用私钥对请求内容加签,然后需要同时将请求内容和签名一并发给服务端: 服务端收到请求后,使用客户端给的公钥对请求内容和签名进行验签,以确定请求是来自客户端的. 生成公私钥 # 生成 1024 位长度的私钥 openssl genrsa -out private-key.pem 1024 # 生成公

  • Golang实现AES对称加密算法实例详解

    目录 前言 前置知识 生成随机数 生成随机字符串 加密和解密 加密 解密 总结 前言 安全总是相对的,对于敏感数据最好要有一定保护措施,尤其是在线数据,通过加密可转换信息为编码,从而防止非法获取.对开发者来说,加密本质是保护应用程序数据,假设我们以明文存储用户密码,可能会导致信息泄露.使用密文在一定程度上可避免信息落入他人之手,本文介绍Golang的对称加密算法实现. 前置知识 在正式学习加密解密之前,首先看看如何生成随机数,以及为什么要随机数. 生成随机数 编程中生成随机数或字符串非常重要,它

  • Go 语言简单实现Vigenere加密算法

    目录 Vigenere 加密算法 Go 代码 Vigenere 加密算法 该密码由意大利密码学家 Giovan Battista Bellaso 于 1553 年发明,但几个世纪以来一直归功于 16 世纪的法国密码学家 Blaise de Vigenère,他在 1586 年设计了类似的密码. Vigenere Cipher 是一种加密字母文本的方法.它使用一种简单的多字母表替换形式.多字母密码是基于替换的任何密码,使用多个替换字母表.原始文本的加密是使用 Vigenère square 或 V

  • Go 加密解密算法小结

    目录 前言 md5 hmac sha1 AES ECB模式 CBC模式 CRT模式 CFB模式 OFB模式 RSA加密 参考: 前言 加密解密在实际开发中应用比较广泛,常用加解密分为:“对称式”.“非对称式”和”数字签名“. 对称式:对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法.具体算法主要有DES算法,3DES算法,TDEA算法,Blowfish算法,RC5算法,IDEA算法. 非对称加密(公钥加密):指加密和解密使用不同密钥的加密算法,也称为公私钥加密.具体算法主要有RSA.E

  • Go中使用加密算法的方法

    目录 哈希算法 加密模式 对称加密 ⾮对称加密 椭圆曲线加密算法ECC 数字签名 字符编码/解码 巨人的肩膀 哈希算法 md5 128bit,16字节 如:md5 ("hello world!") = fc3ff98e8c6a0d3087d515c0473f8677 // 32位16进制数字 func Test(t *testing.T) { //方法一 str := "hello world!" has := md5.Sum([]byte(str)) md5str

  • golang常用加密解密算法总结(AES、DES、RSA、Sha1、MD5)

    目录 关于加密解密 AES DES RSA MD5 Sha1 Base64 在项目开发过程中,当操作一些用户的隐私信息,诸如密码.帐户密钥等数据时,往往需要加密后可以在网上传输.这时,需要一些高效地.简单易用的加密算法加密数据,然后把加密后的数据存入数据库或进行其他操作:当需要读取数据时,把加密后的数据取出来,再通过算法解密. 关于加密解密 当前我们项目中常用的加解密的方式无非三种. 对称加密, 加解密都使用的是同一个密钥, 其中的代表就是AES.DES 非对加解密, 加解密使用不同的密钥, 其

  • Golang中常见加密算法的总结

    目录 1.md5 加密——不可逆 2.hmacsha 加密——不可逆 hmac-md5加密 hamacsha1 加密 hamacsha 256 加密 hmacsha512加密 hamasha 调用 3.Sha 加密——不可逆 sha1 sha256 sha512 sha调用 4.base 加密 解密 加密 解密 base64 调用 5.AES 加密 CBC方式 ECB方式 CFB 方式 6.RSA加密 RSA加密 RSA分段加密 7.DES加密 内置库完成 使用第三方库 8.3DES加密算法 如

  • 盘点Python 爬虫中的常见加密算法

    目录 前言 1. 基础常识 2. Base64伪加密 3. MD5加密 4. AES/DES对称加密 1.密钥 2.填充 3.模式 前言 今天小编就带着大家来盘点一下数据抓取过程中这些主流的加密算法,它们有什么特征.加密的方式有哪些等等,知道了这些之后对于我们逆向破解这些加密的参数会起到不少的帮助! 相信大家在数据抓取的时候,会碰到很多加密的参数,例如像是"token"."sign"等等,今天小编就带着大家来盘点一下数据抓取过程中这些主流的加密算法,它们有什么特征.

  • Golang中反射的常见用法分享

    目录 根据类型做不同处理 标准库 json 中的示例 基本类型的反射 数组类型的反射 chan 反射 map 反射 迭代反射 map 对象 slice 反射 string 反射 interface/Pointer 反射 结构体的反射 遍历结构体字段 根据名称或索引获取结构体字段 修改结构体字段 结构体方法调用 是否实现接口 结构体的 tag 修改结构体未导字段 方法的反射 入参和返回值 通过反射调用方法 总结 在之前的两篇文章 <深入理解 go reflect - 反射基本原理>.<深入

  • iOS中MD5加密算法的介绍和使用

    前言 软件开发过程中,对数据进行加密是保证数据安全的重要手段,常见的加密有Base64加密和MD5加密.Base64加密是可逆的,MD5加密目前来说一般是不可逆的. MD5生成的是固定的128bit,即128个0和1的二进制位,而在实际应用开发中,通常是以16进制输出的,所以正好就是32位的16进制,说白了也就是32个16进制的数字. MD5主要特点是 不可逆,相同数据的MD5值肯定一样,不同数据的MD5值不一样(也不是绝对的,但基本是不能一样的). MD5算法还具有以下性质: 1.压缩性:任意

  • golang中struct和[]byte的相互转换示例

    在网络传输过程中,经常会这样处理:socket接收到数据,先获取其消息头,然后再做各种不同的业务处理.在解析消息头的时候的方法有多种多样.其中最为高效解析消息头的方法就是直接把数据头部分强制类型转换为对应的消息头结构体.这种做法在C/C++中非常的常见.而golang其实也是可以这样子做的.类似这样的应用,直接类型转换获取消息对应的解析方法其实效率会相对较高. golang中struct和[]byte的转换方法,其实就是用到了golang中的unsafe包加上类型转换 , 约束:struct中不

  • Golang中匿名组合实现伪继承的方法

    "Go语言的面向对象机制与一般语言不同. 它没有类层次结构, 甚至可以说没有类: 仅仅通过组合( 而不是继承) 简单的对象来构建复杂的对象." -- <Go语言圣经> 1.匿名组合 1.1 匿名组合定义 golang中组合语法,就是在一个类中,引入了另一个类,如 type Logger struct{ } type Work struct{ log Logger } type Work2 struct{ log *Logger } func (Logger)Info(v .

  • 在Golang中使用Redis的方法示例

    周五上班的主要任务是在公司老平台上用redis处理一个队列问题,顺便复习了一下redis操作的基础知识,回来后就想着在自己的博客demo里,用redis来优化一些使用场景,学习一下golang开发下redis的使用. Redis简单介绍 简介 关于Redis的讨论,其实在现在的后台开发中已经是个老生常谈的问题,基本上也是后端开发面试的基本考察点.其中 Redis的背景介绍和细节说明在这里就不赘述.不管怎么介绍,核心在于Redis是一个基于内存的key-value的多数据结构存储,并可以提供持久化

  • iOS中常见的几种加密方法总结

    前言 在我们日常开发中,加密是必不可少的一部分,而普通加密方法是讲密码进行加密后保存到用户偏好设置中,钥匙串是以明文形式保存,但是不知道存放的具体位置,下面本文将详细给大家介绍iOS中常见的几种加密方法,下面话不多说了,来一起看看详细的介绍吧. 一. base64加密 base64 编码是现代密码学的基础 基本原理: 原本是 8个bit 一组表示数据,改为 6个bit一组表示数据,不足的部分补零,每 两个0 用 一个 = 表示 用base64 编码之后,数据长度会变大,增加了大约 1/3 左右.

  • golang中为什么不存在三元运算符详解

    三元运算符广泛存在于其他语言中,比如: python: val = trueValue if expr else falseValue javascript: const val = expr ? trueValue : falseValue c.c++: const char *val = expr ? "trueValue" : "falseValue"; 然而,被广泛支持的三目运算符在golang中却是不存在的!如果我们写出类似下面的代码: val := ex

  • Golang中基础的命令行模块urfave/cli的用法说明

    前言 相信只要部署过线上服务,都知道启动参数一定是必不可少的,当你在不同的网络.硬件.软件环境下去启动一个服务的时候,总会有一些启动参数是不确定的,这时候就需要通过命令行模块去解析这些参数,urfave/cli是Golang中一个简单实用的命令行工具. 安装 通过 go get github.com/urfave/cli 命令即可完成安装. 正文 使用了urfave/cli之后,你的程序就会变成一个命令行程序,以下就是通过urfave/cli创建的一个最简单的命令行程序,它设定了一些基础的信息,

随机推荐