发布时间:2024-12-22 22:04:35
在当今的数字化时代,数据的加密和解密已经成为保护隐私和确保数据安全的重要工具。而golang作为一种高效且易于使用的编程语言,也提供了强大的加解密功能,使开发人员能够轻松实现各种加密算法。本文将介绍如何使用golang进行流式加解密。
AES(Advanced Encryption Standard)是一种最常用的对称加密算法之一,它使用相同的密钥来加密和解密数据。在golang中,我们可以使用crypto/aes包来实现AES加解密。以下是一个简单的示例代码:
package main import ( "crypto/aes" "crypto/cipher" "fmt" ) func encrypt(plainText []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } cipherText := make([]byte, aes.BlockSize+len(plainText)) iv := cipherText[:aes.BlockSize] if _, err := rand.Read(iv); err != nil { return nil, err } mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(cipherText[aes.BlockSize:], plainText) return cipherText, nil } func decrypt(cipherText []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } if len(cipherText) < aes.BlockSize { return nil, errors.New("cipher text too short") } iv := cipherText[:aes.BlockSize] cipherText = cipherText[aes.BlockSize:] mode := cipher.NewCBCDecrypter(block, iv) mode.CryptBlocks(cipherText, cipherText) return cipherText, nil } func main() { plainText := []byte("Hello, World!") key := []byte("abcdefghijklmnop") cipherText, err := encrypt(plainText, key) if err != nil { fmt.Println("Encryption error:", err) return } fmt.Printf("Cipher Text: %x\n", cipherText) decryptedPlainText, err := decrypt(cipherText, key) if err != nil { fmt.Println("Decryption error:", err) return } fmt.Println("Decrypted Plain Text:", string(decryptedPlainText)) }
在上述代码中,我们通过crypto/aes包中的NewCipher函数创建一个AES解密块。然后,我们使用NewCBCEncrypter和NewCBCDecrypter函数分别创建加密器和解密器。经过加密后,我们打印出了密文,并通过解密函数将其解密为明文。
RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,它使用一对公私钥来加密和解密数据。在golang中,我们可以使用crypto/rsa包来实现RSA加解密。以下是一个简单的示例代码:
package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" ) func encrypt(plainText []byte, publicKey []byte) ([]byte, error) { block, _ := pem.Decode(publicKey) if block == nil { return nil, errors.New("failed to decode public key") } publicKey, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey.(*rsa.PublicKey), plainText) if err != nil { return nil, err } return cipherText, nil } func decrypt(cipherText []byte, privateKey []byte) ([]byte, error) { block, _ := pem.Decode(privateKey) if block == nil { return nil, errors.New("failed to decode private key") } privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return nil, err } plainText, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText) if err != nil { return nil, err } return plainText, nil } func main() { plainText := []byte("Hello, World!") publicKey := []byte(` -----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY----- `) privateKey := []byte(` -----BEGIN RSA PRIVATE KEY----- ... -----END RSA PRIVATE KEY----- `) cipherText, err := encrypt(plainText, publicKey) if err != nil { fmt.Println("Encryption error:", err) return } fmt.Printf("Cipher Text: %x\n", cipherText) decryptedPlainText, err := decrypt(cipherText, privateKey) if err != nil { fmt.Println("Decryption error:", err) return } fmt.Println("Decrypted Plain Text:", string(decryptedPlainText)) }
在上述代码中,我们通过crypto/rsa包中的EncryptPKCS1v15和DecryptPKCS1v15函数分别使用公钥和私钥进行加解密。我们首先使用编码的PEM格式的密钥,并使用Pem.Decode函数对其进行解码。然后,我们使用x509.ParsePKIXPublicKey和x509.ParsePKCS1PrivateKey函数将解码后的密钥转换为RSA公钥和私钥。最后,我们使用EncryptPKCS1v15和DecryptPKCS1v15函数进行加解密。
以上示例中我们展示了如何对数据进行流式加解密,但是在实际应用中,我们也需要对文件进行加解密。golang中提供了io.Writer和io.Reader接口,可以将加解密算法应用于文件操作中。以下示例代码展示了如何使用流式加解密进行文件加解密:
package main import ( "crypto/aes" "crypto/cipher" "crypto/rand" "io" "log" "os" ) func encryptFile(inputFilePath string, outputFilePath string, key []byte) error { inputFile, err := os.Open(inputFilePath) if err != nil { return err } defer inputFile.Close() outputFile, err := os.OpenFile(outputFilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return err } defer outputFile.Close() block, err := aes.NewCipher(key) if err != nil { return err } iv := make([]byte, aes.BlockSize) if _, err := rand.Read(iv); err != nil { return err } outputFile.Write(iv) mode := cipher.NewCBCEncrypter(block, iv) writer := &cipher.StreamWriter{S: mode, W: outputFile} if _, err := io.Copy(writer, inputFile); err != nil { return err } return nil } func decryptFile(inputFilePath string, outputFilePath string, key []byte) error { inputFile, err := os.Open(inputFilePath) if err != nil { return err } defer inputFile.Close() outputFile, err := os.OpenFile(outputFilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return err } defer outputFile.Close() block, err := aes.NewCipher(key) if err != nil { return err } iv := make([]byte, aes.BlockSize) if _, err := inputFile.Read(iv); err != nil { return err } mode := cipher.NewCBCDecrypter(block, iv) reader := &cipher.StreamReader{S: mode, R: inputFile} if _, err := io.Copy(outputFile, reader); err != nil { return err } return nil } func main() { inputFilePath := "input.txt" encryptedFilePath := "encrypted.bin" decryptedFilePath := "decrypted.txt" plainText := []byte("Hello, World!") key := []byte("abcdefghijklmnop") if err := os.WriteFile(inputFilePath, plainText, 0644); err != nil { log.Fatal(err) } if err := encryptFile(inputFilePath, encryptedFilePath, key); err != nil { log.Fatal(err) } if err := decryptFile(encryptedFilePath, decryptedFilePath, key); err != nil { log.Fatal(err) } }
以上代码中,我们通过使用os.Open、os.OpenFile和os.WriteFile函数对文件进行