加密必备技能:深入理解RSA与AES

简介: 加密必备技能:深入理解RSA与AES

1. RSA 简介

RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,使用一对公私钥进行加解密。

公钥用于加密数据,私钥用于解密数据或签名。RSA 的安全性基于大整数因子分解的难度。

Go 语言提供了crypto/rsa包实现 RSA 加解密功能。该包包含了生成密钥对、加密、解密等功能。

公钥加密、私钥解密示例:


package main
import (  "crypto/rand"  "crypto/rsa"  "crypto/x509"  "encoding/pem"  "fmt")
func main() {  // 生成RSA密钥对  privateKey, err := rsa.GenerateKey(rand.Reader, 2048)  if err != nil {    panic(err)  }
  // 使用公钥加密  message := []byte("Hello, RSA!")  ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, &privateKey.PublicKey, message)  if err != nil {    panic(err)  }
  // 使用私钥解密  plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, ciphertext)  if err != nil {    panic(err)  }
  fmt.Printf("Original: %s\nDecrypted: %s\n", message, plaintext)}


 

2. AES 简介

AES(Advanced Encryption Standard)是对称加密算法,使用相同的密钥进行加解密。它支持 128、192 和 256 位密钥长度。

Go 语言的crypto/aes包提供了 AES 加解密功能。密钥长度可以是 16、24 或 32 字节。

加减密示例:


package main
import (  "crypto/aes"  "crypto/cipher"  "crypto/rand"  "fmt"  "io")
func main() {  // 生成随机AES密钥  key := make([]byte, 32)  if _, err := rand.Read(key); err != nil {    panic(err)  }
  // 加密  plaintext := []byte("Hello, AES!")  ciphertext := encryptAES(plaintext, key)
  // 解密  decryptedText := decryptAES(ciphertext, key)
  fmt.Printf("Original: %s\nDecrypted: %s\n", plaintext, decryptedText)}
// 加密函数func encryptAES(plaintext, key []byte) []byte {  block, err := aes.NewCipher(key)  if err != nil {    panic(err)  }
  ciphertext := make([]byte, aes.BlockSize+len(plaintext))  iv := ciphertext[:aes.BlockSize]  if _, err := io.ReadFull(rand.Reader, iv); err != nil {    panic(err)  }
  mode := cipher.NewCBCEncrypter(block, iv)  mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
  return ciphertext}
// 解密函数func decryptAES(ciphertext, key []byte) []byte {  block, err := aes.NewCipher(key)  if err != nil {    panic(err)  }
  if len(ciphertext) < aes.BlockSize {    panic("Ciphertext too short")  }
  iv := ciphertext[:aes.BlockSize]  ciphertext = ciphertext[aes.BlockSize:]
  mode := cipher.NewCBCDecrypter(block, iv)  mode.CryptBlocks(ciphertext, ciphertext)
  return ciphertext}


 

3. RSA 数字签名

RSA 数字签名用于验证数据的完整性和来源。私钥用于签名,公钥用于验证签名。

实现签名和验证示例:


package main
import (  "crypto"  "crypto/rand"  "crypto/rsa"  "fmt")
func main() {  // 生成RSA密钥对  privateKey, err := rsa.GenerateKey(rand.Reader, 2048)  if err != nil {    panic(err)  }
  // 签名  message := []byte("Hello, RSA Signature!")  signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, message)  if err != nil {    panic(err)  }
  // 验证签名  err = rsa.VerifyPKCS1v15(&privateKey.PublicKey, crypto.SHA256, message, signature)  if err != nil {    fmt.Println("Signature verification failed")  } else {    fmt.Println("Signature verified successfully")  }}


 

4. RSA 与 AES 结合使用

流程:

客户端生成 AES 密钥,并使用服务器公钥加密该密钥。

客户端使用生成的 AES 密钥加密数据。

服务端使用私钥解密收到的 AES 密钥。

服务端使用解密后的 AES 密钥解密数据。

实现加密通信示例:


// 客户端package main
import (  "crypto/rand"  "crypto/rsa"  "fmt")
func main() {  // 生成RSA密钥对  clientPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048)  if err != nil {    panic(err)  }
  // 模拟发送公钥给服务器  clientPublicKey := &clientPrivateKey.PublicKey
  // 生成AES密钥  aesKey := make([]byte, 32)  if _, err := rand.Read(aesKey); err != nil {    panic(err)  }
  // 使用服务器公钥加密AES密钥  encryptedAESKey, err := rsa.EncryptPKCS1v15(rand.Reader, clientPublicKey, aesKey)  if err != nil {    panic(err)  }
  fmt.Printf("Encrypted AES Key: %x\n", encryptedAESKey)}
// 服务端package main
import (  "crypto/rand"  "crypto/rsa"  "fmt")
func main() {  // 生成RSA密钥对  serverPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048)  if err != nil {    panic(err)  }
  // 模拟接收客户端发送的加密的AES密钥  // 在实际应用中,此处应从网络或其他安全通道接收密钥  // encryptedAESKey := ...
  // 使用私钥解密AES密钥  decryptedAESKey, err
 := rsa.DecryptPKCS1v15(rand.Reader, serverPrivateKey, encryptedAESKey)  if err != nil {    panic(err)  }
  fmt.Printf("Decrypted AES Key: %x\n", decryptedAESKey)}

客户端:数据 AES 加密+AES 密钥 RSA 加密


// 客户端package main
import (  "crypto/aes"  "crypto/cipher"  "crypto/rand"  "crypto/rsa"  "fmt"  "io")
func main() {  // 生成RSA密钥对  clientPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048)  if err != nil {    panic(err)  }
  // 模拟发送公钥给服务器  clientPublicKey := &clientPrivateKey.PublicKey
  // 生成AES密钥  aesKey := make([]byte, 32)  if _, err := rand.Read(aesKey); err != nil {    panic(err)  }
  // 使用服务器公钥加密AES密钥  encryptedAESKey, err := rsa.EncryptPKCS1v15(rand.Reader, clientPublicKey, aesKey)  if err != nil {    panic(err)  }
  // 加密数据  message := []byte("Hello, Secure Communication!")  ciphertext := encryptAES(message, aesKey)
  fmt.Printf("Encrypted AES Key: %x\n", encryptedAESKey)  fmt.Printf("Encrypted Data: %x\n", ciphertext)}
// 加密函数func encryptAES(plaintext, key []byte) []byte {  block, err := aes.NewCipher(key)  if err != nil {    panic(err)  }
  ciphertext := make([]byte, aes.BlockSize+len(plaintext))  iv := ciphertext[:aes.BlockSize]  if _, err := io.ReadFull(rand.Reader, iv); err != nil {    panic(err)  }
  mode := cipher.NewCBCEncrypter(block, iv)  mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
  return ciphertext}

服务端:AES 密钥 RSA 解密+数据 AES 解密


// 服务端package main
import (  "crypto/aes"  "crypto/cipher"  "crypto/rand"  "crypto/rsa"  "fmt"  "io")
func main() {  // 生成RSA密钥对  serverPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048)  if err != nil {    panic(err)  }
  // 模拟接收客户端发送的加密的AES密钥和数据  // 在实际应用中,此处应从网络或其他安全通道接收数据  // encryptedAESKey := ...  // encryptedData := ...
  // 使用私钥解密AES密钥  decryptedAESKey, err := rsa.DecryptPKCS1v15(rand.Reader, serverPrivateKey, encryptedAESKey)  if err != nil {    panic(err)  }
  // 解密数据  decryptedData := decryptAES(encryptedData, decryptedAESKey)
  fmt.Printf("Decrypted AES Key: %x\n", decryptedAESKey)  fmt.Printf("Decrypted Data: %s\n", decryptedData)}
// 解密函数func decryptAES(ciphertext, key []byte) []byte {  block, err := aes.NewCipher(key)  if err != nil {    panic(err)  }
  if len(ciphertext) < aes.BlockSize {    panic("Ciphertext too short")  }
  iv := ciphertext[:aes.BlockSize]  ciphertext = ciphertext[aes.BlockSize:]
  mode := cipher.NewCBCDecrypter(block, iv)  mode.CryptBlocks(ciphertext, ciphertext)
  return ciphertext}


 

5. 实用功能

5.1 PEM 编码解析

PEM 编码用于将二进制数据转换为可打印的 ASCII 字符。在加解密中,PEM 编码通常用于存储密钥。


package main
import (  "crypto/rand"  "crypto/rsa"  "crypto/x509"  "encoding/pem"  "fmt")
func main() {  // 生成RSA密钥对  privateKey, err := rsa.GenerateKey(rand.Reader, 2048)  if err != nil {    panic(err)  }
  // 将私钥编码为PEM格式  privateKeyPEM := pem.EncodeToMemory(&pem.Block{    Type:  "RSA PRIVATE KEY",    Bytes: x509.MarshalPKCS1PrivateKey(privateKey),  })
  // 将PEM格式的私钥解析回RSA密钥  block, _ := pem.Decode(privateKeyPEM)  parsedPrivateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)  if err != nil {    panic(err)  }
  fmt.Println("Private keys are equal:", *parsedPrivateKey == *privateKey)}

5.2 CBC 模式

CBC(Cipher Block Chaining)是一种分组密码的工作模式,每个明文块与前一个密文块进行异或操作。在crypto/aes 中,使用 cipher.NewCBCDecrypter 和 cipher.NewCBCEncrypter 创建 CBC 模式加解密器。

5.3 PKCS#7 数据填充

PKCS#7 是一种填充方案,用于将数据填充到块大小的整数倍。在 crypto/aes 中,可以使用 crypto/rand 包的 Read 函数进行填充。

5.4 16 位 IV 生成

IV(Initialization Vector)是在加密过程中使用的初始值。在 AES 中,IV 通常是一个固定长度的随机数,可以使用 crypto/rand 包生成。

5.5 Base64 编码

Base64 编码是一种将二进制数据转换为可打印 ASCII 字符的方法。在加解密中,Base64 编码通常用于传输密文。

5.6 加密密文存储

在实际应用中,密文通常需要存储在数据库或文件中。安全存储密文以及密钥的管理尤为重要。


 

6. 性能优化

选择 RSA 密钥长度时,需权衡安全性和性能。较长的密钥更安全,但可能导致性能下降。

一些平台提供硬件加速 AES 指令集,可显著提高性能。在选择平台时,考虑硬件支持。

Go 语言中可使用 goroutines 实现并发加密,提高系统的吞吐量。


 

7. 总结

Go 语言的 crypto 包提供了强大的加密功能,涵盖了对称加密(如 AES)和非对称加密(如 RSA)等多种算法,满足不同场景的需求。

Go 语言的 crypto 包设计简洁且易用,提供了清晰的 API 和示例,使开发者能够轻松实现各种加密需求。

结合 RSA 和 AES 的加密方案在网络通信中广泛应用,通过 RSA 实现密钥的安全交换,再利用 AES 进行快速的数据加解密,既保障了通信的机密性,又确保了密钥的安全性。

总体而言,Go 语言提供了完善的加密功能和工具,使开发者能够轻松实现安全可靠的加密通信系统。

在应用中,务必根据实际需求选择适当的加密算法、密钥长度,并采取适当的措施保障密钥的安全存储和传输,以确保系统的整体安全性。

目录
相关文章
|
2月前
|
算法 安全 网络安全
非对称加密算法RSA
RSA是一种基于数论的非对称加密算法,依赖大整数质因数分解的困难性保证安全性。它生成公钥和私钥,公钥加密,私钥解密,适用于数据加密、数字签名和互联网安全等领域。尽管计算效率低、适合小量数据处理,但由于其兼容性、安全性和广泛应用于SSL/TLS、数字签名等,RSA仍是主流加密算法之一。
49 2
|
2月前
|
Linux 数据安全/隐私保护 Windows
aes加密在linux下会生成随机key的解决办法
aes加密在linux下会生成随机key的解决办法
39 2
|
2月前
|
PHP 数据安全/隐私保护
在PHP中使用AES进行加密和解密
在PHP中使用AES进行加密和解密
159 0
|
2月前
|
算法 数据库 数据安全/隐私保护
rsa加密解密,使用rsa对密码加密
rsa加密解密,使用rsa对密码加密
|
1天前
|
算法 安全 搜索推荐
AES(Advanced Encryption Standard)是一种广泛使用的对称密钥加密算法,由美国国家标准技术研究所(NIST)制定。
AES(Advanced Encryption Standard)是一种广泛使用的对称密钥加密算法,由美国国家标准技术研究所(NIST)制定。
20 9
|
18天前
|
Java PHP 数据安全/隐私保护
php和Java配合 aes
php和Java配合 aes加密
13 1
|
26天前
|
安全 网络安全 数据安全/隐私保护
非对称加密的日常实践应用:以RSA加密为例
**RSA加密简介与Python实现** RSA,一种非对称加密技术,基于大数因子分解,用于数据加密和完整性保护。本文介绍了RSA基本原理,包括密钥生成(选取大质数p和q,计算n和φ(n),选择公钥指数e和私钥指数d),并展示了使用Python `cryptography` 库生成密钥对、加密和解密消息的代码示例。通过这些步骤,读者可理解RSA在网络安全中的应用,如HTTPS和数字签名。
29 3
|
26天前
|
存储 安全 数据库
对称加密的日常实践应用:以AES为例的加密解密指南
**摘要:** 本文介绍了对称加密算法AES在数据安全中的应用,强调了其在文件、通信和数据库加密中的重要性。通过Python示例展示了如何使用`cryptography`库实现AES-256的加密和解密,涉及密钥生成、CBC模式及PKCS7填充。同时,提醒注意密钥管理、模式选择和填充方式的选择对加密安全性的影响。
46 1
|
12天前
|
算法 安全 网络安全
支付系统,网络安全06----支付安全---,机密性,加密算法,目前最流行的加密算法,AES加密算法,目前最流行的非对称加密算法RSA,对称加密和非对称加密的优缺点,非对称加密是基于非常复杂的数学算法
支付系统,网络安全06----支付安全---,机密性,加密算法,目前最流行的加密算法,AES加密算法,目前最流行的非对称加密算法RSA,对称加密和非对称加密的优缺点,非对称加密是基于非常复杂的数学算法
|
19天前
|
存储 安全 算法
RSA非对称加密算法中的密钥对生成与传输
RSA非对称加密算法的密钥对生成与传输是信息安全领域的核心问题之一。密钥生成过程需要保证随机性和安全性,而密钥的传输则需要选择适当的方式来确保其保密性和完整性。通过合理的密钥管理和保护措施,可以有效地利用RSA算法保护通信安全,防止信息泄露和篡改。在实际应用中,用户和系统管理员需要结合具体情况选择最佳的密钥生成和传输策略,以达到最佳的安全性和效率。