🔐 对称加密工具

使用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;
}