亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go語言實現(xiàn)對稱加密和非對稱加密的示例代碼

 更新時間:2024年01月30日 10:11:07   作者:242030  
本文主要介紹了Go語言實現(xiàn)對稱加密和非對稱加密的示例代碼,通過實際代碼示例展示了如何在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ù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • GO workPool的線程池實現(xiàn)

    GO workPool的線程池實現(xiàn)

    本文主要介紹了GO workPool的線程池實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • Go語言中高效地處理集合的方法小結

    Go語言中高效地處理集合的方法小結

    在?Go?語言中,處理集合(如切片、映射等)時,可以通過多種方式提高效率,本文為大家整理了一些常見的方法,有需要的小伙伴可以了解一下
    2025-02-02
  • go語言中的defer關鍵字

    go語言中的defer關鍵字

    這篇文章介紹了go語言中的defer關鍵字,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • golang兩種調用rpc的方法

    golang兩種調用rpc的方法

    這篇文章主要介紹了golang兩種調用rpc的方法,結合實例形式分析了Go語言調用rpc的原理與實現(xiàn)方法,需要的朋友可以參考下
    2016-07-07
  • golang int64轉int的方法

    golang int64轉int的方法

    這篇文章主要介紹了golang int64轉int,本文給大家提供兩種方法 ,將 golang int64 轉換為golang int,結合實例代碼給大家分享轉換方法,需要的朋友可以參考下
    2023-01-01
  • golang語言map全方位介紹

    golang語言map全方位介紹

    本文主要介紹了golang語言map全方位介紹,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 使用?pprof?進行性能分析的方法詳解

    使用?pprof?進行性能分析的方法詳解

    pprof?是?Go?語言中用于性能分析的一個強大工具,它可以幫助開發(fā)人員找到應用程序中的性能瓶頸,并提供詳細的分析報告,本文將介紹如何使用?pprof?進行性能分析,需要的朋友可以參考下
    2023-05-05
  • go字符串拼接方式及性能比拼小結

    go字符串拼接方式及性能比拼小結

    在golang中字符串的拼接方式有多種,本文將會介紹比較常用的幾種方式,并且對各種方式進行壓測,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • 使用Go語言實現(xiàn)Yaml編碼和解碼的方法詳解

    使用Go語言實現(xiàn)Yaml編碼和解碼的方法詳解

    在這篇文章中,我們將介紹如何使用Go語言編寫代碼來實現(xiàn)Yaml編碼和解碼,文中有詳細的代碼示例供大家參考,對大家的學習和工作有一定的幫助,需要的朋友可以參考下
    2023-11-11
  • 淺談Go切片的值修改是否會覆蓋數組的值?

    淺談Go切片的值修改是否會覆蓋數組的值?

    本文主要介紹了淺談Go切片的值修改是否會覆蓋數組的值,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下?
    2022-02-02

最新評論