🔐 对称加密工具
使用AES、SM4、ChaCha20等对称加密算法对数据进行加密和解密
什么是对称加密?
对称加密是一种密码学技术,使用相同的密钥进行数据的加密和解密。发送方和接收方必须事先共享相同的密钥,这个密钥既用于加密明文,也用于解密密文。
核心特点
- 加密解密使用同一密钥
- 运算速度快,适合大量数据
- 密钥管理复杂,需要安全分发
- 常用算法:AES、SM4、ChaCha20等
主要应用场景
- 文件和数据库加密
- VPN和网络通信加密
- 敏感信息存储保护
- 实时通信和消息加密
安全提示
密钥的安全性直接决定了加密数据的安全性。请确保使用强密钥、安全存储和传输密钥,并定期更换密钥。生产环境中请使用专业的密钥管理系统。
算法设置
密钥管理
输入数据
字符数: 0
加密结果
输出长度: 0
算法详情与实现示例
算法基本信息
算法名称:AES-256-GCM
密钥长度:256 bits
IV长度:96 bits
安全等级:非常高
性能:良好
算法特点
• AES (Advanced Encryption Standard) 是美国联邦政府采用的对称加密标准
• 采用替换-置换网络 (SPN) 结构,具有优秀的安全性和性能
• 支持128、192、256位密钥长度,256位提供最高安全级别
• GCM模式提供认证加密,CBC模式需要额外的完整性验证
使用场景与案例
文件加密
保护敏感文档和数据文件
HTTPS通信
TLS/SSL协议中的数据传输
数据库加密
敏感字段的透明加密
代码实现示例
JavaScript (Node.js + crypto)
const crypto = require('crypto');
// AES-256-GCM 加密示例
class SymmetricCrypto {
constructor() {
this.algorithm = 'aes-256-gcm';
}
// 生成随机密钥
generateKey() {
return crypto.randomBytes(32);
}
// 生成随机IV
generateIV() {
return crypto.randomBytes(12);
}
// 加密数据
encrypt(plaintext, key, iv) {
const cipher = crypto.createCipher(this.algorithm, key);
cipher.setAutoPadding(true);
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
encrypted += cipher.final('hex');
return {
encrypted,
authTag: cipher.getAuthTag ? cipher.getAuthTag() : null
};
}
// 解密数据
decrypt(encrypted, key, iv, authTag) {
const decipher = crypto.createDecipher(this.algorithm, key);
if (authTag) {
decipher.setAuthTag(authTag);
}
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
}
// 使用示例
const cryptoInstance = new SymmetricCrypto();
const key = cryptoInstance.generateKey();
const iv = cryptoInstance.generateIV();
const plaintext = "Hello, World!";
const { encrypted, authTag } = cryptoInstance.encrypt(plaintext, key, iv);
console.log('加密结果:', encrypted);
const decrypted = cryptoInstance.decrypt(encrypted, key, iv, authTag);
console.log('解密结果:', decrypted);Python (cryptography库)
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
import os
import base64
class SymmetricCrypto:
def __init__(self):
self.backend = default_backend()
def generate_key(self):
"""生成随机密钥"""
return os.urandom(32) # AES-256 需要32字节密钥
def generate_iv(self):
"""生成随机IV"""
return os.urandom(12) # GCM模式需要12字节IV
def encrypt(self, plaintext: str, key: bytes, iv: bytes) -> dict:
"""加密数据"""
# AES-GCM加密
algorithm = algorithms.AES(key)
mode = modes.GCM(iv)
cipher = Cipher(algorithm, mode, backend=self.backend)
encryptor = cipher.encryptor()
plaintext_bytes = plaintext.encode('utf-8')
ciphertext = encryptor.update(plaintext_bytes) + encryptor.finalize()
result = {
'ciphertext': base64.b64encode(ciphertext).decode('ascii'),
'iv': base64.b64encode(iv).decode('ascii'),
'tag': base64.b64encode(encryptor.tag).decode('ascii')
}
return result
def decrypt(self, encrypted_data: dict, key: bytes) -> str:
"""解密数据"""
ciphertext = base64.b64decode(encrypted_data['ciphertext'])
iv = base64.b64decode(encrypted_data['iv'])
tag = base64.b64decode(encrypted_data['tag'])
algorithm = algorithms.AES(key)
mode = modes.GCM(iv, tag)
cipher = Cipher(algorithm, mode, backend=self.backend)
decryptor = cipher.decryptor()
plaintext = decryptor.update(ciphertext) + decryptor.finalize()
return plaintext.decode('utf-8')
# 使用示例
crypto = SymmetricCrypto()
key = crypto.generate_key()
iv = crypto.generate_iv()
plaintext = "Hello, World!"
# 加密
encrypted = crypto.encrypt(plaintext, key, iv)
print(f"加密结果: {encrypted['ciphertext']}")
# 解密
decrypted = crypto.decrypt(encrypted, key)
print(f"解密结果: {decrypted}")Java (javax.crypto)
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.security.SecureRandom;
import java.util.Base64;
public class SymmetricCrypto {
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
private static final int KEY_LENGTH = 256;
private static final int IV_LENGTH = 12;
// 生成随机密钥
public static SecretKey generateKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
keyGenerator.init(KEY_LENGTH);
return keyGenerator.generateKey();
}
// 生成随机IV
public static byte[] generateIV() {
byte[] iv = new byte[IV_LENGTH];
new SecureRandom().nextBytes(iv);
return iv;
}
// 加密数据
public static EncryptionResult encrypt(String plaintext, SecretKey key, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
// GCM模式
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, gcmSpec);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes("UTF-8"));
return new EncryptionResult(
Base64.getEncoder().encodeToString(ciphertext),
Base64.getEncoder().encodeToString(iv)
);
}
// 解密数据
public static String decrypt(EncryptionResult encrypted, SecretKey key) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
byte[] iv = Base64.getDecoder().decode(encrypted.getIv());
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.DECRYPT_MODE, key, gcmSpec);
byte[] ciphertext = Base64.getDecoder().decode(encrypted.getCiphertext());
byte[] plaintext = cipher.doFinal(ciphertext);
return new String(plaintext, "UTF-8");
}
// 使用示例
public static void main(String[] args) throws Exception {
String plaintext = "Hello, World!";
// 生成密钥和IV
SecretKey key = generateKey();
byte[] iv = generateIV();
// 加密
EncryptionResult encrypted = encrypt(plaintext, key, iv);
System.out.println("加密结果: " + encrypted.getCiphertext());
// 解密
String decrypted = decrypt(encrypted, key);
System.out.println("解密结果: " + decrypted);
}
// 结果类
static class EncryptionResult {
private final String ciphertext;
private final String iv;
public EncryptionResult(String ciphertext, String iv) {
this.ciphertext = ciphertext;
this.iv = iv;
}
public String getCiphertext() { return ciphertext; }
public String getIv() { return iv; }
}
}Go (crypto包)
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"fmt"
"io"
)
type SymmetricCrypto struct {
keySize int
}
func NewSymmetricCrypto() *SymmetricCrypto {
return &SymmetricCrypto{
keySize: 32, // AES-256 需要32字节密钥
}
}
// 生成随机密钥
func (sc *SymmetricCrypto) GenerateKey() ([]byte, error) {
key := make([]byte, sc.keySize)
_, err := rand.Read(key)
return key, err
}
// 生成随机nonce
func (sc *SymmetricCrypto) GenerateNonce() ([]byte, error) {
nonce := make([]byte, 12) // GCM模式需要12字节nonce
_, err := rand.Read(nonce)
return nonce, err
}
// AES-GCM加密
func (sc *SymmetricCrypto) Encrypt(plaintext string, key []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
nonce := make([]byte, gcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return "", err
}
ciphertext := gcm.Seal(nonce, nonce, []byte(plaintext), nil)
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// 解密数据
func (sc *SymmetricCrypto) Decrypt(ciphertextB64 string, key []byte) (string, error) {
ciphertext, err := base64.StdEncoding.DecodeString(ciphertextB64)
if err != nil {
return "", err
}
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
nonceSize := gcm.NonceSize()
nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
return "", err
}
return string(plaintext), nil
}
func main() {
crypto := NewSymmetricCrypto()
// 生成密钥
key, err := crypto.GenerateKey()
if err != nil {
panic(err)
}
plaintext := "Hello, World!"
// 加密
encrypted, err := crypto.Encrypt(plaintext, key)
if err != nil {
panic(err)
}
fmt.Printf("加密结果: %s\n", encrypted)
// 解密
decrypted, err := crypto.Decrypt(encrypted, key)
if err != nil {
panic(err)
}
fmt.Printf("解密结果: %s\n", decrypted)
}C++ (OpenSSL)
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
#include <string>
#include <vector>
#include <iostream>
#include <iomanip>
#include <sstream>
class SymmetricCrypto {
private:
static const int KEY_SIZE = 32; // AES-256需要32字节密钥
static const int IV_SIZE = 12; // GCM模式需要12字节IV
public:
// 生成随机密钥
std::vector<unsigned char> generateKey() {
std::vector<unsigned char> key(KEY_SIZE);
if (RAND_bytes(key.data(), KEY_SIZE) != 1) {
throw std::runtime_error("Failed to generate key");
}
return key;
}
// 生成随机IV
std::vector<unsigned char> generateIV() {
std::vector<unsigned char> iv(IV_SIZE);
if (RAND_bytes(iv.data(), IV_SIZE) != 1) {
throw std::runtime_error("Failed to generate IV");
}
return iv;
}
// AES-GCM加密
std::string encrypt(const std::string& plaintext,
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv) {
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if (!ctx) throw std::runtime_error("Failed to create context");
// AES-256-GCM加密
if (EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(),
NULL, key.data(), iv.data()) != 1) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to initialize encryption");
}
std::vector<unsigned char> ciphertext(plaintext.length() + AES_BLOCK_SIZE);
int len;
int ciphertext_len;
// 加密数据
if (EVP_EncryptUpdate(ctx, ciphertext.data(), &len,
reinterpret_cast<const unsigned char*>(plaintext.c_str()),
plaintext.length()) != 1) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to encrypt data");
}
ciphertext_len = len;
// 完成加密
if (EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len) != 1) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to finalize encryption");
}
ciphertext_len += len;
// 获取认证标签
std::vector<unsigned char> tag(16);
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag.data()) != 1) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to get auth tag");
}
EVP_CIPHER_CTX_free(ctx);
// 转换为Base64(包含认证标签)
ciphertext.resize(ciphertext_len);
ciphertext.insert(ciphertext.end(), tag.begin(), tag.end());
return toBase64(ciphertext);
}
// 解密数据
std::string decrypt(const std::string& ciphertextB64,
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv) {
auto ciphertext = fromBase64(ciphertextB64);
// 分离密文和认证标签
std::vector<unsigned char> tag(ciphertext.end() - 16, ciphertext.end());
ciphertext.resize(ciphertext.size() - 16);
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if (!ctx) throw std::runtime_error("Failed to create context");
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(),
NULL, key.data(), iv.data()) != 1) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to initialize decryption");
}
std::vector<unsigned char> plaintext(ciphertext.size() + AES_BLOCK_SIZE);
int len;
int plaintext_len;
if (EVP_DecryptUpdate(ctx, plaintext.data(), &len,
ciphertext.data(), ciphertext.size()) != 1) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to decrypt data");
}
plaintext_len = len;
// 设置认证标签
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag.data()) != 1) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to set auth tag");
}
if (EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &len) != 1) {
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to finalize decryption");
}
plaintext_len += len;
EVP_CIPHER_CTX_free(ctx);
return std::string(reinterpret_cast<char*>(plaintext.data()), plaintext_len);
}
private:
// Base64编码辅助函数(实际使用中建议使用专门的库)
std::string toBase64(const std::vector<unsigned char>& data) {
const char* chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string result;
// ... 完整Base64编码实现
return result;
}
std::vector<unsigned char> fromBase64(const std::string& base64) {
std::vector<unsigned char> result;
// ... 完整Base64解码实现
return result;
}
};
// 使用示例
int main() {
SymmetricCrypto crypto;
auto key = crypto.generateKey();
auto iv = crypto.generateIV();
std::string plaintext = "Hello, World!";
try {
// 加密
std::string encrypted = crypto.encrypt(plaintext, key, iv);
std::cout << "加密结果: " << encrypted << std::endl;
// 解密
std::string decrypted = crypto.decrypt(encrypted, key, iv);
std::cout << "解密结果: " << decrypted << std::endl;
} catch (const std::exception& e) {
std::cerr << "错误: " << e.what() << std::endl;
}
return 0;
}