Go語言實現(xiàn)對稱加密和非對稱加密的示例代碼
對稱加密和非對稱加密的區(qū)別主要有以下幾個方面:
1、密鑰的使用:對稱加密中,加密和解密使用的是同一個密鑰,而非對稱加密則使用兩個不同的密鑰,一般
使用公鑰進行加密,私鑰進行解密。
2、速度和效率:對稱加密解密的速度比較快,適合數據比較長時的使用,而非對稱加密和解密花費的時間
長、速度相對較慢,只適合對少量數據的使用。
3、安全性:對稱加密的安全性相對較低,因為通信雙方使用相同的秘鑰,如果一方的秘鑰遭泄露,那么整個
通信就會被破解。而非對稱加密使用一對秘鑰,一個用來加密,一個用來解密,而且公鑰是公開的,私鑰是自
己保存的,不需要像對稱加密那樣在通信之前要先同步秘鑰,因此其安全性更好。
4、密鑰分發(fā):在對稱加密中,需要在通信雙方之間安全地共享密鑰。如果沒有安全的通道來共享密鑰,可能
會被黑客截獲,導致數據泄露。而非對稱加密則不需要在通信之前共享密鑰,因此更加安全。
在實際應用中,對稱加密和非對稱加密經常結合使用,以充分發(fā)揮它們各自的優(yōu)點。例如,可以使用對稱加密來加
密大量數據,然后使用非對稱加密來安全地分發(fā)對稱加密的密鑰。
1、對稱加密
1.1 AES
package main import ( "bytes" "crypto/aes" "crypto/cipher" "encoding/base64" "fmt" ) // AES加密 func main() { // AES加密占16、24或32字節(jié) key := "12345678abcdefgh" // 加密的字符串 str := "hello world!" fmt.Println("加密前的字符串:", str) cipherText, _ := SCEncryptString(str, key) fmt.Println("加密后的字符串:", cipherText) originalText, _ := SCDecryptString(cipherText, key) fmt.Println("解密后的字符串:", originalText) } // 對稱加密 func SCEncrypt(originalBytes, key []byte) ([]byte, error) { // 1、實例化密碼器block(參數為密鑰) block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() // 2、對明文進行填充(參數為原始字節(jié)切片和密碼對象的區(qū)塊個數) paddingBytes := PKCS5Padding(originalBytes, blockSize) // 3、實例化加密模式(參數為密碼對象和密鑰) blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 4、對填充字節(jié)后的明文進行加密(參數為加密字節(jié)切片和填充字節(jié)切片) cipherBytes := make([]byte, len(paddingBytes)) blockMode.CryptBlocks(cipherBytes, paddingBytes) return cipherBytes, nil } // 對稱解密 func SCDecrypt(cipherBytes, key []byte) ([]byte, error) { // 1、實例化密碼器block(參數為密鑰) block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() // 2、實例化解密模式(參數為密碼對象和密鑰) blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // 3、對密文進行解密(參數為填充字節(jié)切片和加密字節(jié)切片) paddingBytes := make([]byte, len(cipherBytes)) blockMode.CryptBlocks(paddingBytes, cipherBytes) // 4、去除填充的字節(jié)(參數為填充切片) originalBytes := PKCS5UnPadding(paddingBytes) return originalBytes, nil } // 封裝字符串對稱加密 func SCEncryptString(originalText, key string) (string, error) { cipherBytes, err := SCEncrypt([]byte(originalText), []byte(key)) if err != nil { return "", err } // base64編碼(encoded) base64str := base64.StdEncoding.EncodeToString(cipherBytes) return base64str, nil } // 封裝字符串對稱解密 func SCDecryptString(cipherText, key string) (string, error) { // base64解碼(decode) cipherBytes, _ := base64.StdEncoding.DecodeString(cipherText) cipherBytes, err := SCDecrypt(cipherBytes, []byte(key)) if err != nil { return "", err } return string(cipherBytes), nil } // 末尾填充字節(jié) func PKCS5Padding(data []byte, blockSize int) []byte { // 要填充的值和個數 padding := blockSize - len(data)%blockSize // 要填充的單個二進制值 slice1 := []byte{byte(padding)} // 要填充的二進制數組 slice2 := bytes.Repeat(slice1, padding) // 填充到數據末端 return append(data, slice2...) } // 末尾填充0 func ZerosPadding(data []byte, blockSize int) []byte { // 要填充的個數 padding := blockSize - len(data)%blockSize // 要填充的單個0數據 slice1 := []byte{0} // 要填充的0二進制數組 slice2 := bytes.Repeat(slice1, padding) // 填充到數據末端 return append(data, slice2...) } // 去除填充的字節(jié) func PKCS5UnPadding(data []byte) []byte { // 獲取二進制數組最后一個數值 unpadding := data[len(data)-1] // 截取開始至總長度減去填充值之間的有效數據 result := data[:(len(data) - int(unpadding))] return result } // 去除填充的0 func ZerosUnPadding(data []byte) []byte { // 去除滿足條件的子切片 return bytes.TrimRightFunc(data, func(r rune) bool { return r == 0 }) }
package main import ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/base64" "fmt" "io" ) // AES加密 // AES加密占16、24或32字節(jié) var encryptionKey = []byte("12345678abcdefgh") func encrypt(data []byte) (string, error) { block, err := aes.NewCipher(encryptionKey) if err != nil { return "", err } ciphertext := make([]byte, aes.BlockSize+len(data)) iv := ciphertext[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(ciphertext[aes.BlockSize:], data) return base64.URLEncoding.EncodeToString(ciphertext), nil } func decrypt(encodedData string) ([]byte, error) { ciphertext, err := base64.URLEncoding.DecodeString(encodedData) if err != nil { return nil, err } block, err := aes.NewCipher(encryptionKey) if err != nil { return nil, err } if len(ciphertext) < aes.BlockSize { return nil, fmt.Errorf("加密數據長度無效") } iv := ciphertext[:aes.BlockSize] ciphertext = ciphertext[aes.BlockSize:] stream := cipher.NewCFBDecrypter(block, iv) stream.XORKeyStream(ciphertext, ciphertext) return ciphertext, nil } func main() { data := []byte("Hello World!") encryptedData, err := encrypt(data) if err != nil { fmt.Println("加密失敗:", err) return } fmt.Println("加密后的數據:", encryptedData) decryptedData, err := decrypt(encryptedData) if err != nil { fmt.Println("解密失敗:", err) return } fmt.Println("解密后的數據:", string(decryptedData)) }
1.2 DES
package main import ( "bytes" "crypto/cipher" "crypto/des" "encoding/base64" "fmt" ) // DES加密 func main() { // DES密鑰占8字節(jié) key := "1234abcd" // 加密的字符串 str := "hello world!" fmt.Println("加密前的字符串:", str) cipherText, _ := SCEncryptString(str, key) fmt.Println("加密后的字符串:", cipherText) originalText, _ := SCDecryptString(cipherText, key) fmt.Println("解密后的字符串:", originalText) } // 對稱加密 func SCEncrypt(originalBytes, key []byte) ([]byte, error) { // 1、實例化密碼器block(參數為密鑰) block, err := des.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() // 2、對明文進行填充(參數為原始字節(jié)切片和密碼對象的區(qū)塊個數) paddingBytes := PKCS5Padding(originalBytes, blockSize) // 3、實例化加密模式(參數為密碼對象和密鑰) blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 4、對填充字節(jié)后的明文進行加密(參數為加密字節(jié)切片和填充字節(jié)切片) cipherBytes := make([]byte, len(paddingBytes)) blockMode.CryptBlocks(cipherBytes, paddingBytes) return cipherBytes, nil } // 對稱解密 func SCDecrypt(cipherBytes, key []byte) ([]byte, error) { // 1、實例化密碼器block(參數為密鑰) block, err := des.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() // 2、實例化解密模式(參數為密碼對象和密鑰) blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // 3、對密文進行解密(參數為填充字節(jié)切片和加密字節(jié)切片) paddingBytes := make([]byte, len(cipherBytes)) blockMode.CryptBlocks(paddingBytes, cipherBytes) // 4、去除填充的字節(jié)(參數為填充切片) originalBytes := PKCS5UnPadding(paddingBytes) return originalBytes, nil } // 封裝字符串對稱加密 func SCEncryptString(originalText, key string) (string, error) { cipherBytes, err := SCEncrypt([]byte(originalText), []byte(key)) if err != nil { return "", err } // base64編碼(encoded) base64str := base64.StdEncoding.EncodeToString(cipherBytes) return base64str, nil } // 封裝字符串對稱解密 func SCDecryptString(cipherText, key string) (string, error) { // base64解碼(decode) cipherBytes, _ := base64.StdEncoding.DecodeString(cipherText) cipherBytes, err := SCDecrypt(cipherBytes, []byte(key)) if err != nil { return "", err } return string(cipherBytes), nil } // 末尾填充字節(jié) func PKCS5Padding(data []byte, blockSize int) []byte { // 要填充的值和個數 padding := blockSize - len(data)%blockSize // 要填充的單個二進制值 slice1 := []byte{byte(padding)} // 要填充的二進制數組 slice2 := bytes.Repeat(slice1, padding) // 填充到數據末端 return append(data, slice2...) } // 末尾填充0 func ZerosPadding(data []byte, blockSize int) []byte { // 要填充的個數 padding := blockSize - len(data)%blockSize // 要填充的單個0數據 slice1 := []byte{0} // 要填充的0二進制數組 slice2 := bytes.Repeat(slice1, padding) // 填充到數據末端 return append(data, slice2...) } // 去除填充的字節(jié) func PKCS5UnPadding(data []byte) []byte { // 獲取二進制數組最后一個數值 unpadding := data[len(data)-1] // 截取開始至總長度減去填充值之間的有效數據 result := data[:(len(data) - int(unpadding))] return result } // 去除填充的0 func ZerosUnPadding(data []byte) []byte { // 去除滿足條件的子切片 return bytes.TrimRightFunc(data, func(r rune) bool { return r == 0 }) }
package main import ( "crypto/cipher" "crypto/des" "crypto/rand" "encoding/base64" "fmt" "io" ) // DES加密 // DES密鑰占8字節(jié) var encryptionKey = []byte("1234abcd") func encrypt(data []byte) (string, error) { block, err := des.NewCipher(encryptionKey) if err != nil { return "", err } ciphertext := make([]byte, des.BlockSize+len(data)) iv := ciphertext[:des.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(ciphertext[des.BlockSize:], data) return base64.URLEncoding.EncodeToString(ciphertext), nil } func decrypt(encodedData string) ([]byte, error) { ciphertext, err := base64.URLEncoding.DecodeString(encodedData) if err != nil { return nil, err } block, err := des.NewCipher(encryptionKey) if err != nil { return nil, err } if len(ciphertext) < des.BlockSize { return nil, fmt.Errorf("加密數據長度無效") } iv := ciphertext[:des.BlockSize] ciphertext = ciphertext[des.BlockSize:] stream := cipher.NewCFBDecrypter(block, iv) stream.XORKeyStream(ciphertext, ciphertext) return ciphertext, nil } func main() { data := []byte("Hello") encryptedData, err := encrypt(data) if err != nil { fmt.Println("加密失敗:", err) return } fmt.Println("加密后的數據:", encryptedData) decryptedData, err := decrypt(encryptedData) if err != nil { fmt.Println("解密失敗:", err) return } fmt.Println("解密后的數據:", string(decryptedData)) }
1.3 3DES
package main import ( "bytes" "crypto/cipher" "crypto/des" "encoding/base64" "fmt" ) // 3DES加密 func main() { // 3DES密鑰占24字節(jié) key := "abcdefghijklmn0123456789" // 加密的字符串 str := "hello world!" fmt.Println("加密前的字符串:", str) cipherText, _ := SCEncryptString(str, key) fmt.Println("加密后的字符串:", cipherText) originalText, _ := SCDecryptString("3eS626HB2R9ZGcOAYLuWCw==", key) fmt.Println("解密后的字符串:", originalText) } // 對稱加密 func SCEncrypt(originalBytes, key []byte) ([]byte, error) { // 1、實例化密碼器block(參數為密鑰) block, err := des.NewTripleDESCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() // 2、對明文進行填充(參數為原始字節(jié)切片和密碼對象的區(qū)塊個數) paddingBytes := PKCS5Padding(originalBytes, blockSize) // 3、實例化加密模式(參數為密碼對象和密鑰) blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 4、對填充字節(jié)后的明文進行加密(參數為加密字節(jié)切片和填充字節(jié)切片) cipherBytes := make([]byte, len(paddingBytes)) blockMode.CryptBlocks(cipherBytes, paddingBytes) return cipherBytes, nil } // 對稱解密 func SCDecrypt(cipherBytes, key []byte) ([]byte, error) { // 1、實例化密碼器block(參數為密鑰) block, err := des.NewTripleDESCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() // 2、實例化解密模式(參數為密碼對象和密鑰) blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // 3、對密文進行解密(參數為填充字節(jié)切片和加密字節(jié)切片) paddingBytes := make([]byte, len(cipherBytes)) blockMode.CryptBlocks(paddingBytes, cipherBytes) // 4、去除填充的字節(jié)(參數為填充切片) originalBytes := PKCS5UnPadding(paddingBytes) return originalBytes, nil } // 封裝字符串對稱加密 func SCEncryptString(originalText, key string) (string, error) { cipherBytes, err := SCEncrypt([]byte(originalText), []byte(key)) if err != nil { return "", err } // base64編碼(encoded) base64str := base64.StdEncoding.EncodeToString(cipherBytes) return base64str, nil } // 封裝字符串對稱解密 func SCDecryptString(cipherText, key string) (string, error) { // base64解碼(decode) cipherBytes, _ := base64.StdEncoding.DecodeString(cipherText) cipherBytes, err := SCDecrypt(cipherBytes, []byte(key)) if err != nil { return "", err } return string(cipherBytes), nil } // 末尾填充字節(jié) func PKCS5Padding(data []byte, blockSize int) []byte { // 要填充的值和個數 padding := blockSize - len(data)%blockSize // 要填充的單個二進制值 slice1 := []byte{byte(padding)} // 要填充的二進制數組 slice2 := bytes.Repeat(slice1, padding) // 填充到數據末端 return append(data, slice2...) } // 末尾填充0 func ZerosPadding(data []byte, blockSize int) []byte { // 要填充的個數 padding := blockSize - len(data)%blockSize // 要填充的單個0數據 slice1 := []byte{0} // 要填充的0二進制數組 slice2 := bytes.Repeat(slice1, padding) // 填充到數據末端 return append(data, slice2...) } // 去除填充的字節(jié) func PKCS5UnPadding(data []byte) []byte { // 獲取二進制數組最后一個數值 unpadding := data[len(data)-1] // 截取開始至總長度減去填充值之間的有效數據 result := data[:(len(data) - int(unpadding))] return result } // 去除填充的0 func ZerosUnPadding(data []byte) []byte { // 去除滿足條件的子切片 return bytes.TrimRightFunc(data, func(r rune) bool { return r == 0 }) }
package main import ( "crypto/cipher" "crypto/des" "crypto/rand" "encoding/base64" "fmt" "io" ) // 3DES加密 // 3DES密鑰占24字節(jié) var encryptionKey = []byte("abcdefghijklmn0123456789") func encrypt(data []byte) (string, error) { block, err := des.NewTripleDESCipher(encryptionKey) if err != nil { return "", err } ciphertext := make([]byte, des.BlockSize+len(data)) iv := ciphertext[:des.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(ciphertext[des.BlockSize:], data) return base64.URLEncoding.EncodeToString(ciphertext), nil } func decrypt(encodedData string) ([]byte, error) { ciphertext, err := base64.URLEncoding.DecodeString(encodedData) if err != nil { return nil, err } block, err := des.NewTripleDESCipher(encryptionKey) if err != nil { return nil, err } if len(ciphertext) < des.BlockSize { return nil, fmt.Errorf("加密數據長度無效") } iv := ciphertext[:des.BlockSize] ciphertext = ciphertext[des.BlockSize:] stream := cipher.NewCFBDecrypter(block, iv) stream.XORKeyStream(ciphertext, ciphertext) return ciphertext, nil } func main() { data := []byte("Hello") encryptedData, err := encrypt(data) if err != nil { fmt.Println("加密失敗:", err) return } fmt.Println("加密后的數據:", encryptedData) decryptedData, err := decrypt(encryptedData) if err != nil { fmt.Println("解密失敗:", err) return } fmt.Println("解密后的數據:", string(decryptedData)) }
2、非對稱加密算法RSA
2.1 生成密鑰對
生成密鑰對,分別存儲到公鑰文件(public.pem),私鑰文件中(private.pem)。
package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "log" "os" ) func main() { if err := GenerateRSAKey(); err != nil { log.Fatal("密鑰生成失敗!") } log.Println("密鑰生成成功!") } // 生成密鑰對并保存到文件 func GenerateRSAKey() error { // 1、RSA生成私鑰文件的核心步驟 // 1)、生成RSA密鑰對 // 密鑰長度,默認值為1024位 bits := 1024 privateKer, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { return err } // 2)、將私鑰對象轉換成DER編碼形式 derPrivateKer := x509.MarshalPKCS1PrivateKey(privateKer) // 3)、創(chuàng)建私鑰pem文件 file, err := os.Create("../certs/private.pem") if err != nil { return err } // 4)、對密鑰信息進行編碼,寫入到私鑰文件中 block := &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: derPrivateKer, } err = pem.Encode(file, block) if err != nil { return err } // 2、RSA生成公鑰文件的核心步驟 // 1)、生成公鑰對象 publicKey := &privateKer.PublicKey // 2)、將公鑰對象序列化為DER編碼格式 derPublicKey, err := x509.MarshalPKIXPublicKey(publicKey) if err != nil { return err } // 3)、創(chuàng)建公鑰pem文件 file, err = os.Create("../certs/public.pem") if err != nil { return err } // 4)、對公鑰信息進行編碼,寫入到公鑰文件中 block = &pem.Block{ Type: "PUBLIC KEY", Bytes: derPublicKey, } err = pem.Encode(file, block) if err != nil { return err } return nil }
2.2 RSA加密解密過程
公鑰加密,私鑰解密。
加密過程:
- 1、讀取公鑰文件,解析出公鑰對象
- 2、使用公鑰對明文進行加密
解密過程:
- 1、讀取私鑰文件,解析出公鑰對象
- 2、使用私鑰對密文進行解密
package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "fmt" "io/ioutil" ) func main() { str := "Hello World!" encryptstr, _ := RSAEncryptString(str, "../certs/public.pem") fmt.Println(encryptstr) decrypt, _ := RSADecryptString(encryptstr, "../certs/private.pem") fmt.Println(decrypt) } // RSA加密字節(jié)數組,返回字節(jié)數組 func RSAEncrypt(originalBytes []byte, filename string) ([]byte, error) { // 1、讀取公鑰文件,解析出公鑰對象 publicKey, err := ReadParsePublicKey(filename) if err != nil { return nil, err } // 2、RSA加密,參數是隨機數、公鑰對象、需要加密的字節(jié) // Reader是一個全局共享的密碼安全的強大的偽隨機生成器 return rsa.EncryptPKCS1v15(rand.Reader, publicKey, originalBytes) } // RSA解密字節(jié)數組,返回字節(jié)數組 func RSADecrypt(cipherBytes []byte, filename string) ([]byte, error) { // 1、讀取私鑰文件,解析出私鑰對象 privateKey, err := ReadParsePrivaterKey(filename) if err != nil { return nil, err } // 2、ras解密,參數是隨機數、私鑰對象、需要解密的字節(jié) return rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherBytes) } // 讀取公鑰文件,解析出公鑰對象 func ReadParsePublicKey(filename string) (*rsa.PublicKey, error) { // 1、讀取公鑰文件,獲取公鑰字節(jié) publicKeyBytes, err := ioutil.ReadFile(filename) if err != nil { return nil, err } // 2、解碼公鑰字節(jié),生成加密塊對象 block, _ := pem.Decode(publicKeyBytes) if block == nil { return nil, errors.New("公鑰信息錯誤!") } // 3、解析DER編碼的公鑰,生成公鑰接口 publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } // 4、公鑰接口轉型成公鑰對象 publicKey := publicKeyInterface.(*rsa.PublicKey) return publicKey, nil } // 讀取私鑰文件,解析出私鑰對象 func ReadParsePrivaterKey(filename string) (*rsa.PrivateKey, error) { // 1、讀取私鑰文件,獲取私鑰字節(jié) privateKeyBytes, err := ioutil.ReadFile(filename) if err != nil { return nil, err } // 2、對私鑰文件進行編碼,生成加密塊對象 block, _ := pem.Decode(privateKeyBytes) if block == nil { return nil, errors.New("私鑰信息錯誤!") } // 3、解析DER編碼的私鑰,生成私鑰對象 privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return nil, err } return privateKey, nil } // RSA加密字符串,返回base64處理的字符串 func RSAEncryptString(originalText, filename string) (string, error) { cipherBytes, err := RSAEncrypt([]byte(originalText), filename) if err != nil { return "", err } return base64.StdEncoding.EncodeToString(cipherBytes), nil } // RSA解密經過base64處理的加密字符串,返回加密前的明文 func RSADecryptString(cipherlText, filename string) (string, error) { cipherBytes, _ := base64.StdEncoding.DecodeString(cipherlText) originalBytes, err := RSADecrypt(cipherBytes, filename) if err != nil { return "", err } return string(originalBytes), nil }
2.3 數字簽名驗證
加密與簽名的區(qū)別:
- 加密:公鑰加密,私鑰解密
- 簽名:私鑰簽名,公鑰驗證
數字簽名過程:
- 原文的哈希值用自己私鑰簽名,原文+簽名給對方,對方用公鑰驗證簽名時與原文哈希比對。
加密并簽名:
原文用對方公鑰加密,原文的哈希值用自己的私鑰簽名,密文+簽名給對方,對方公鑰驗證簽名和自己私鑰解
密原文的哈希值比對。
package main import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "fmt" "io/ioutil" ) func main() { str := "Hello World!" base64Sig, _ := RSASign([]byte(str), "../certs/private.pem") fmt.Println("簽名后的信息:", base64Sig) err := RSAVerify([]byte(str), base64Sig, "../certs/public.pem") if err == nil { fmt.Println("驗證成功!") } else { fmt.Println("驗證失??!") } } // 私鑰簽名過程 func RSASign(data []byte, filename string) (string, error) { // 1、選擇hash算法,對需要簽名的數據進行hash運算 myhash := crypto.SHA256 hashInstance := myhash.New() hashInstance.Write(data) hashed := hashInstance.Sum(nil) // 2、讀取私鑰文件,解析出私鑰對象 privateKey, err := ReadParsePrivaterKey(filename) if err != nil { return "", err } // 3、RSA數字簽名(參數是隨機數、私鑰對象、哈希類型、簽名文件的哈希串),生成base64編碼的簽名字符串 bytes, err := rsa.SignPKCS1v15(rand.Reader, privateKey, myhash, hashed) if err != nil { return "", err } return base64.StdEncoding.EncodeToString(bytes), nil } // 公鑰驗證簽名過程 func RSAVerify(data []byte, base64Sig, filename string) error { // 1、對base64編碼的簽名內容進行解碼,返回簽名字節(jié) bytes, err := base64.StdEncoding.DecodeString(base64Sig) if err != nil { return err } // 2、選擇hash算法,對需要簽名的數據進行hash運算 myhash := crypto.SHA256 hashInstance := myhash.New() hashInstance.Write(data) hashed := hashInstance.Sum(nil) // 3、讀取公鑰文件,解析出公鑰對象 publicKey, err := ReadParsePublicKey(filename) if err != nil { return err } // 4、RSA驗證數字簽名(參數是公鑰對象、哈希類型、簽名文件的哈希串、簽名后的字節(jié)) return rsa.VerifyPKCS1v15(publicKey, myhash, hashed, bytes) } // 讀取公鑰文件,解析出公鑰對象 func ReadParsePublicKey(filename string) (*rsa.PublicKey, error) { // 1、讀取公鑰文件,獲取公鑰字節(jié) publicKeyBytes, err := ioutil.ReadFile(filename) if err != nil { return nil, err } // 2、解碼公鑰字節(jié),生成加密塊對象 block, _ := pem.Decode(publicKeyBytes) if block == nil { return nil, errors.New("公鑰信息錯誤!") } // 3、解析DER編碼的公鑰,生成公鑰接口 publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } // 4、公鑰接口轉型成公鑰對象 publicKey := publicKeyInterface.(*rsa.PublicKey) return publicKey, nil } // 讀取私鑰文件,解析出私鑰對象 func ReadParsePrivaterKey(filename string) (*rsa.PrivateKey, error) { // 1、讀取私鑰文件,獲取私鑰字節(jié) privateKeyBytes, err := ioutil.ReadFile(filename) if err != nil { return nil, err } // 2、對私鑰文件進行編碼,生成加密塊對象 block, _ := pem.Decode(privateKeyBytes) if block == nil { return nil, errors.New("私鑰信息錯誤!") } // 3、解析DER編碼的私鑰,生成私鑰對象 privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return nil, err } return privateKey, nil }
到此這篇關于Go語言實現(xiàn)對稱加密和非對稱加密的示例代碼的文章就介紹到這了,更多相關Go語言 對稱加密和非對稱加密內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!