欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang常用加密解密算法總結(jié)(AES、DES、RSA、Sha1、MD5)

 更新時間:2022年04月22日 09:42:33   作者:wade3015  
在項目開發(fā)過程中,當操作一些用戶的隱私信息,本文主要主要介紹了golang常用加密解密算法總結(jié)(AES、DES、RSA、Sha1MD5),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

在項目開發(fā)過程中,當操作一些用戶的隱私信息,諸如密碼、帳戶密鑰等數(shù)據(jù)時,往往需要加密后可以在網(wǎng)上傳輸。這時,需要一些高效地、簡單易用的加密算法加密數(shù)據(jù),然后把加密后的數(shù)據(jù)存入數(shù)據(jù)庫或進行其他操作;當需要讀取數(shù)據(jù)時,把加密后的數(shù)據(jù)取出來,再通過算法解密。

關(guān)于加密解密

當前我們項目中常用的加解密的方式無非三種.

  • 對稱加密, 加解密都使用的是同一個密鑰, 其中的代表就是AES、DES
  • 非對加解密, 加解密使用不同的密鑰, 其中的代表就是RSA
  • 簽名算法, 如MD5、SHA1、HMAC等, 主要用于驗證,防止信息被修改, 如:文件校驗、數(shù)字簽名、鑒權(quán)協(xié)議

Base64不是加密算法,它是一種數(shù)據(jù)編碼方式,雖然是可逆的,但是它的編碼方式是公開的,無所謂加密。本文也對Base64編碼方式做了簡要介紹。

AES

AES,即高級加密標準(Advanced Encryption Standard),是一個對稱分組密碼算法,旨在取代DES成為廣泛使用的標準。AES中常見的有三種解決方案,分別為AES-128、AES-192和AES-256。
AES加密過程涉及到4種操作:字節(jié)替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和輪密鑰加(AddRoundKey)。解密過程分別為對應的逆操作。由于每一步操作都是可逆的,按照相反的順序進行解密即可恢復明文。加解密中每輪的密鑰分別由初始密鑰擴展得到。算法中16字節(jié)的明文、密文和輪密鑰都以一個4x4的矩陣表示。

AES 有五種加密模式:電碼本模式(Electronic Codebook Book (ECB))、密碼分組鏈接模式(Cipher Block Chaining (CBC))、計算器模式(Counter (CTR))、密碼反饋模式(Cipher FeedBack (CFB))和輸出反饋模式(Output FeedBack (OFB))

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

func main() {
? ? orig := "hello world"
? ? key := "123456781234567812345678"
? ? fmt.Println("原文:", orig)

? ? encryptCode := AesEncrypt(orig, key)
? ? fmt.Println("密文:" , encryptCode)

? ? decryptCode := AesDecrypt(encryptCode, key)
? ? fmt.Println("解密結(jié)果:", decryptCode)
}

func AesEncrypt(orig string, key string) string {
? ? // 轉(zhuǎn)成字節(jié)數(shù)組
? ? origData := []byte(orig)
? ? k := []byte(key)

? ? // 分組秘鑰
? ? block, _ := aes.NewCipher(k)
? ? // 獲取秘鑰塊的長度
? ? blockSize := block.BlockSize()
? ? // 補全碼
? ? origData = PKCS7Padding(origData, blockSize)
? ? // 加密模式
? ? blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
? ? // 創(chuàng)建數(shù)組
? ? cryted := make([]byte, len(origData))
? ? // 加密
? ? blockMode.CryptBlocks(cryted, origData)

? ? return base64.StdEncoding.EncodeToString(cryted)

}

func AesDecrypt(cryted string, key string) string {
? ? // 轉(zhuǎn)成字節(jié)數(shù)組
? ? crytedByte, _ := base64.StdEncoding.DecodeString(cryted)
? ? k := []byte(key)

? ? // 分組秘鑰
? ? block, _ := aes.NewCipher(k)
? ? // 獲取秘鑰塊的長度
? ? blockSize := block.BlockSize()
? ? // 加密模式
? ? blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
? ? // 創(chuàng)建數(shù)組
? ? orig := make([]byte, len(crytedByte))
? ? // 解密
? ? blockMode.CryptBlocks(orig, crytedByte)
? ? // 去補全碼
? ? orig = PKCS7UnPadding(orig)
? ? return string(orig)
}

//補碼
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)]
}

DES

DES是一種對稱加密算法,又稱為美國數(shù)據(jù)加密標準。DES加密時以64位分組對數(shù)據(jù)進行加密,加密和解密都使用的是同一個長度為64位的密鑰,實際上只用到了其中的56位,密鑰中的第8、16…64位用來作奇偶校驗。DES有ECB(電子密碼本)和CBC(加密塊)等加密模式。

DES算法的安全性很高,目前除了窮舉搜索破解外, 尚無更好的的辦法來破解。其密鑰長度越長,破解難度就越大。
填充和去填充函數(shù)。

func ZeroPadding(ciphertext []byte, blockSize int) []byte {
? ? padding := blockSize - len(ciphertext)%blockSize
? ? padtext := bytes.Repeat([]byte{0}, padding)
? ? return append(ciphertext, padtext...)
}

func ZeroUnPadding(origData []byte) []byte {
? ? return bytes.TrimFunc(origData,
? ? ? ? func(r rune) bool {
? ? ? ? ? ? return r == rune(0)
? ? ? ? })
}

加密。

func Encrypt(text string, key []byte) (string, error) {
    src := []byte(text)
    block, err := des.NewCipher(key)
    if err != nil {
        return "", err
    }
    bs := block.BlockSize()
    src = ZeroPadding(src, bs)
    if len(src)%bs != 0 {
        return "", errors.New("Need a multiple of the blocksize")
    }
    out := make([]byte, len(src))
    dst := out
    for len(src) > 0 {
        block.Encrypt(dst, src[:bs])
        src = src[bs:]
        dst = dst[bs:]
    }
    return hex.EncodeToString(out), nil
}

解密。

func Decrypt(decrypted string , key []byte) (string, error) {
    src, err := hex.DecodeString(decrypted)
    if err != nil {
        return "", err
    }
    block, err := des.NewCipher(key)
    if err != nil {
        return "", err
    }
    out := make([]byte, len(src))
    dst := out
    bs := block.BlockSize()
    if len(src)%bs != 0 {
        return "", errors.New("crypto/cipher: input not full blocks")
    }
    for len(src) > 0 {
        block.Decrypt(dst, src[:bs])
        src = src[bs:]
        dst = dst[bs:]
    }
    out = ZeroUnPadding(out)
    return string(out), nil
}

測試。在這里,DES中使用的密鑰key只能為8位。

func main() {
    key := []byte("2fa6c1e9")
    str :="I love this beautiful world!"
    strEncrypted, err := Encrypt(str, key)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Encrypted:", strEncrypted)
    strDecrypted, err := Decrypt(strEncrypted, key)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Decrypted:", strDecrypted)
}
//Output:
//Encrypted: 5d2333b9fbbe5892379e6bcc25ffd1f3a51b6ffe4dc7af62beb28e1270d5daa1
//Decrypted: I love this beautiful world!

RSA

首先使用openssl生成公私鑰,使用RSA的時候需要提供公鑰和私鑰 , 可以通過openss來生成對應的pem格式的公鑰和私鑰匙

import (
? ? "crypto/rand"
? ? "crypto/rsa"
? ? "crypto/x509"
? ? "encoding/base64"
? ? "encoding/pem"
? ? "errors"
? ? "fmt"
)

// 私鑰生成
//openssl genrsa -out rsa_private_key.pem 1024
var privateKey = []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDcGsUIIAINHfRTdMmgGwLrjzfMNSrtgIf4EGsNaYwmC1GjF/bM
h0Mcm10oLhNrKNYCTTQVGGIxuc5heKd1gOzb7bdTnCDPPZ7oV7p1B9Pud+6zPaco
qDz2M24vHFWYY2FbIIJh8fHhKcfXNXOLovdVBE7Zy682X1+R1lRK8D+vmQIDAQAB
AoGAeWAZvz1HZExca5k/hpbeqV+0+VtobMgwMs96+U53BpO/VRzl8Cu3CpNyb7HY
64L9YQ+J5QgpPhqkgIO0dMu/0RIXsmhvr2gcxmKObcqT3JQ6S4rjHTln49I2sYTz
7JEH4TcplKjSjHyq5MhHfA+CV2/AB2BO6G8limu7SheXuvECQQDwOpZrZDeTOOBk
z1vercawd+J9ll/FZYttnrWYTI1sSF1sNfZ7dUXPyYPQFZ0LQ1bhZGmWBZ6a6wd9
R+PKlmJvAkEA6o32c/WEXxW2zeh18sOO4wqUiBYq3L3hFObhcsUAY8jfykQefW8q
yPuuL02jLIajFWd0itjvIrzWnVmoUuXydwJAXGLrvllIVkIlah+lATprkypH3Gyc
YFnxCTNkOzIVoXMjGp6WMFylgIfLPZdSUiaPnxby1FNM7987fh7Lp/m12QJAK9iL
2JNtwkSR3p305oOuAz0oFORn8MnB+KFMRaMT9pNHWk0vke0lB1sc7ZTKyvkEJW0o
eQgic9DvIYzwDUcU8wJAIkKROzuzLi9AvLnLUrSdI6998lmeYO9x7pwZPukz3era
zncjRK3pbVkv0KrKfczuJiRlZ7dUzVO0b6QJr8TRAA==
-----END RSA PRIVATE KEY-----
`)

// 公鑰: 根據(jù)私鑰生成
//openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
var publicKey = []byte(`
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcGsUIIAINHfRTdMmgGwLrjzfM
NSrtgIf4EGsNaYwmC1GjF/bMh0Mcm10oLhNrKNYCTTQVGGIxuc5heKd1gOzb7bdT
nCDPPZ7oV7p1B9Pud+6zPacoqDz2M24vHFWYY2FbIIJh8fHhKcfXNXOLovdVBE7Z
y682X1+R1lRK8D+vmQIDAQAB
-----END PUBLIC KEY-----
`)

// 加密
func RsaEncrypt(origData []byte) ([]byte, error) {
? ? //解密pem格式的公鑰
? ? block, _ := pem.Decode(publicKey)
? ? if block == nil {
? ? ? ? return nil, errors.New("public key error")
? ? }
? ? // 解析公鑰
? ? pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
? ? if err != nil {
? ? ? ? return nil, err
? ? }
? ? // 類型斷言
? ? pub := pubInterface.(*rsa.PublicKey)
? ? //加密
? ? return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}

// 解密
func RsaDecrypt(ciphertext []byte) ([]byte, error) {
? ? //解密
? ? block, _ := pem.Decode(privateKey)
? ? if block == nil {
? ? ? ? return nil, errors.New("private key error!")
? ? }
? ? //解析PKCS1格式的私鑰
? ? priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
? ? if err != nil {
? ? ? ? return nil, err
? ? }
? ? // 解密
? ? return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}
func main() {
? ? data, _ := RsaEncrypt([]byte("hello world"))
? ? fmt.Println(base64.StdEncoding.EncodeToString(data))
? ? origData, _ := RsaDecrypt(data)
? ? fmt.Println(string(origData))
}?

MD5

MD5的全稱是Message-DigestAlgorithm 5,它可以把一個任意長度的字節(jié)數(shù)組轉(zhuǎn)換成一個定長的整數(shù),并且這種轉(zhuǎn)換是不可逆的。對于任意長度的數(shù)據(jù),轉(zhuǎn)換后的MD5值長度是固定的,而且MD5的轉(zhuǎn)換操作很容易,只要原數(shù)據(jù)有一點點改動,轉(zhuǎn)換后結(jié)果就會有很大的差異。正是由于MD5算法的這些特性,它經(jīng)常用于對于一段信息產(chǎn)生信息摘要,以防止其被篡改。其還廣泛就于操作系統(tǒng)的登錄過程中的安全驗證,比如Unix操作系統(tǒng)的密碼就是經(jīng)過MD5加密后存儲到文件系統(tǒng)中,當用戶登錄時輸入密碼后, 對用戶輸入的數(shù)據(jù)經(jīng)過MD5加密后與原來存儲的密文信息比對,如果相同說明密碼正確,否則輸入的密碼就是錯誤的。
MD5以512位為一個計算單位對數(shù)據(jù)進行分組,每一分組又被劃分為16個32位的小組,經(jīng)過一系列處理后,輸出4個32位的小組,最后組成一個128位的哈希值。對處理的數(shù)據(jù)進行512求余得到N和一個余數(shù),如果余數(shù)不為448,填充1和若干個0直到448位為止,最后再加上一個64位用來保存數(shù)據(jù)的長度,這樣經(jīng)過預處理后,數(shù)據(jù)變成(N+1)x 512位。

加密。Encode 函數(shù)用來加密數(shù)據(jù),Check函數(shù)傳入一個未加密的字符串和與加密后的數(shù)據(jù),進行對比,如果正確就返回true。

func Check(content, encrypted string) bool {
    return strings.EqualFold(Encode(content), encrypted)
}
func Encode(data string) string {
    h := md5.New()
    h.Write([]byte(data))
    return hex.EncodeToString(h.Sum(nil))
}

測試。

func main() {
     strTest := "I love this beautiful world!"
    strEncrypted := "98b4fc4538115c4980a8b859ff3d27e1"
    fmt.Println(Check(strTest, strEncrypted))
}
//Output:
//true

Sha1

package main

import (
?? ?"crypto/sha1"
?? ? "fmt"
)
func main() {
? ?s := "sha1 this string"
? ?//產(chǎn)生一個散列值得方式是 sha1.New(),sha1.Write(bytes),然后 sha1.Sum([]byte{})。這里我們從一個新的散列開始。
? ?h := sha1.New()
? ?//寫入要處理的字節(jié)。如果是一個字符串,需要使用[]byte(s) 來強制轉(zhuǎn)換成字節(jié)數(shù)組。
? ?h.Write([]byte(s))
? ?//這個用來得到最終的散列值的字符切片。Sum 的參數(shù)可以用來都現(xiàn)有的字符切片追加額外的字節(jié)切片:一般不需要要。
? ?bs := h.Sum(nil)
? ?//SHA1 值經(jīng)常以 16 進制輸出,例如在 git commit 中。使用%x 來將散列結(jié)果格式化為 16 進制字符串。
? ?fmt.Println(s)
? ?fmt.Printf("%x\n", bs)
}

Base64

Base64是一種任意二進制到文本字符串的編碼方法,常用于在URL、Cookie、網(wǎng)頁中傳輸少量二進制數(shù)據(jù)。

首先使用Base64編碼需要一個含有64個字符的表,這個表由大小寫字母、數(shù)字、+和/組成。采用Base64編碼處理數(shù)據(jù)時,會把每三個字節(jié)共24位作為一個處理單元,再分為四組,每組6位,查表后獲得相應的字符即編碼后的字符串。編碼后的字符串長32位,這樣,經(jīng)Base64編碼后,原字符串增長1/3。如果要編碼的數(shù)據(jù)不是3的倍數(shù),最后會剩下一到兩個字節(jié),Base64編碼中會采用\x00在處理單元后補全,編碼后的字符串最后會加上一到兩個 = 表示補了幾個字節(jié)。

const (
? ?base64Table = "IJjkKLMNO567PQX12RVW3YZaDEFGbcdefghiABCHlSTUmnopqrxyz04stuvw89+/"

)

var coder = base64.NewEncoding(base64Table)

func Base64Encode(src []byte) []byte { ? ? ? ? //編碼
? ?return []byte(coder.EncodeToString(src))
}

func Base64Decode(src []byte) ([]byte, error) { ? //解碼
? ?return coder.DecodeString(string(src))
}

到此這篇關(guān)于golang常用加密解密算法總結(jié)(AES、DES、RSA、Sha1MD5)的文章就介紹到這了,更多相關(guān)golang 加密解密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言計算指定年月天數(shù)的方法

    Go語言計算指定年月天數(shù)的方法

    這篇文章主要介紹了Go語言計算指定年月天數(shù)的方法,實例分析了Go語言操作時間的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • go 迭代string數(shù)組操作 go for string[]

    go 迭代string數(shù)組操作 go for string[]

    這篇文章主要介紹了go 迭代string數(shù)組操作 go for string[],具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言時間管理利器之深入解析time模塊的實戰(zhàn)技巧

    Go語言時間管理利器之深入解析time模塊的實戰(zhàn)技巧

    本文深入解析了Go語言標準庫中的time模塊,揭示了其高效用法和實用技巧,通過學習time模塊的三大核心類型(Time、Duration、Timer/Ticker)以及高頻使用場景,開發(fā)者可以更好地處理時間相關(guān)的任務,感興趣的朋友一起看看吧
    2025-03-03
  • Go的gin參數(shù)校驗中的validator庫詳解

    Go的gin參數(shù)校驗中的validator庫詳解

    這篇文章主要介紹了Go的gin參數(shù)校驗之validator庫,使用 validator 以后,只需要在定義結(jié)構(gòu)體時使用 binding 或 validate tag標識相關(guān)校驗規(guī)則,就可以進行參數(shù)校驗了,而不用自己單獨去寫常見的校驗規(guī)則,需要的朋友可以參考下
    2023-08-08
  • Go?time包AddDate使用解惑實例詳解

    Go?time包AddDate使用解惑實例詳解

    這篇文章主要為大家介紹了Go?time包AddDate使用解惑實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • 解決老版本goland無法調(diào)試新版本go的問題

    解決老版本goland無法調(diào)試新版本go的問題

    這篇文章主要給大家介紹了如何解決老版本goland無法調(diào)試新版本go的問題,文中通過代碼示例給大家講解的非常詳細,具有一定的參考價值,需要的朋友可以參考下
    2023-11-11
  • Go歸并排序算法的實現(xiàn)方法

    Go歸并排序算法的實現(xiàn)方法

    歸并排序采用的也是分治的策略,把原本的問題先分解成一些小問題進行求解,再把這些小問題各自的答案修整到一起得到原本問題的答案,從而達到分而治之的目的,對Go歸并排序算法相關(guān)知識感興趣的朋友一起看看吧
    2022-04-04
  • Go interface接口聲明實現(xiàn)及作用詳解

    Go interface接口聲明實現(xiàn)及作用詳解

    這篇文章主要為大家介紹了Go interface接口聲明實現(xiàn)及作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • golang hack插件開發(fā)動態(tài)鏈接庫實例探究

    golang hack插件開發(fā)動態(tài)鏈接庫實例探究

    這篇文章主要為大家介紹了golang hack插件開發(fā)動態(tài)鏈接庫實例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • 詳解如何在Golang中執(zhí)行shell命令

    詳解如何在Golang中執(zhí)行shell命令

    這篇文章主要為大家詳細介紹了在 golang 中執(zhí)行 shell 命令的多種方法和場景,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-02-02

最新評論