接口加密之AES&RSA

引言:加密算法 加密算法是一种用于保护数据安全的数学函数或一组规则,通过特定的加密密钥将明文(原始数据)转换为密文(加密后的数据),以防止未经授权的访问和篡改。加密算法可以分为两大类:对称加密算法和非对称加密算法。

  • 对称加密算法:对称加密算法使用相同的密钥进行加密和解密。常见的对称加密算法包括AES(高级加密标准)、DES(数据加密标准)和3DES(三重数据加密标准)。储。
  • 非对称加密算法:非对称加密算法使用一对密钥,即公钥和私钥。公钥用于加密,私钥用于解密。常见的非对称加密算法包括RSA、ECC(椭圆曲线加密)和DSA(数字签名算法)。
一、方案一(对称加密AES)

1、特点

  • 安全性高:AES算法经过了严格的审查和测试,至今未被公开破解。
  • 效率高:AES算法的加密和解密速度较快,适用于各种硬件和软件平台。
  • 灵活性强:AES支持多种密钥长度,包括128位、192位和256位,满足不同安全需求。
  • 对称密钥加密:AES采用对称密钥算法,这意味着加密和解密使用相同的密钥。这简化了加密过程并加快了速度,特别适用于保护大量数据。
  • 分组密码方法:AES使用分组密码方法,将数据分成块(通常为128位)并分别加密每个块。这种结构通过确保每个数据块独立加密来增强安全性。

2、应用场景

  • 通信加密 :广泛应用于通信加密领域,如HTTPS、VPN等,保障通信过程的安全性。
  • 数据存储加密 :可应用于数据存储加密,如硬盘加密、数据库加密等,保护存储数据的安全性。
  • 数字签名 :可用于数字签名,保障数字证书的安全性。

3、方案实现(spring+vue)

import CryptoJS from "crypto-js"

/**
 *  AES工具类
 * @returns {{encrypt: (function(*): string), decrypt: (function(*): string)}}
 * @constructor
 */
const AESUtil = () => {
    const SECRET_KEY_ = "xxxxxxxx"

    // 解密
    const decrypt = (value) => {
        // 过滤双引号
        const filter = value.replace(/^"|"$/g, '');
        let decrypt = CryptoJS.AES.decrypt({ciphertext: CryptoJS.enc.Base64.parse(filter)}, CryptoJS.enc.Base64.parse(SECRET_KEY_), {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7,
        });
        return decrypt.toString(CryptoJS.enc.Utf8)
    };

    // 加密
    const encrypt = (value) => {
        let encrypt = CryptoJS.AES.encrypt(value, CryptoJS.enc.Utf8.parse(SECRET_KEY_), {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7
        });
        return encrypt.toString()
    };

    // 测试函数
    const asyncTest = async (parameters) => {
        // 异步操作
        try {
            const response = await fetch("/api/encrypted-data");
            const value = await response.text();

            // 解密数据
            const decryptedData = decrypt(value)
            console.log("解密后的数据:", JSON.parse(decryptedData))
        } catch (error) {
            console.error("解密失败:", error)
        }
    };

    return {
        decrypt,
        encrypt,
    };
}
const AES = AESUtil();
export {AES}
  /**
     * @return {@code String }
     * @description: 加密
     * @param: [data, key]
     * @author: BrownSugar
     * @date: 2025-01-10 06:31:59
     **/
    public static String encrypt(String data, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(key), AES_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
 /**
     * @return {@code String }
     * @description: 解密
     * @param: [encryptedData, key]
     * @author: BrownSugar
     * @date: 2025-01-10 06:32:05
     **/
    public static String decrypt(String encryptedData, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(key), AES_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }
 /**
     * @return {@code String }
     * @description: 生成密钥
     * @param: []
     * @author: BrownSugar
     * @date: 2025-01-10 06:32:09
     **/
    public static String generateKey() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance(AES_ALGORITHM);
        keyGen.init(256); // AES 128位密钥
        SecretKey secretKey = keyGen.generateKey();
        return Base64.getEncoder().encodeToString(secretKey.getEncoded());
    }
二、方案二(非对称加密RSA)

1、特点

  • 非对称加密:RSA是一种非对称加密算法,使用一对密钥(公钥和私钥)进行加密和解密。公钥可以公开,私钥必须保密。
  • 安全性高:RSA通常需要更长的密钥长度(如2048或4096位)才能达到与AES相当的安全性。由于其较短的密钥,AES通常更快,但RSA在安全的密钥交换和数字签名方面非常有用。
  • 效率较低:RSA在加密大量数据时效率较低,通常用于加密小数据传输,例如在SSL/TLS握手中建立安全连接

2、应用场景

  • 密钥交换:RSA常用于加密对称加密算法(如AES)的密钥,然后将加密后的密钥传输给接收方,接收方使用私钥解密得到对称密钥,后续使用对称密钥进行高效的加密通信。
  • 数字签名:RSA用于数字签名,验证发送者的身份和数据的完整性。

3、方案实现(spring+vue)

import Encrypt from 'encryptlong/bin/jsencrypt.min'
import { Base64 } from 'js-base64';

/**
 * RSA工具类
 * @returns {{test: test, encrypt: (function(*): string), decrypt: (function(*): string)}}
 * @constructor
 */
const RSAUtil = () => {
    //公钥
    const PUBLIC_KEY = 'xxxx'

    //私钥
    const PRIVATE_KEY = 'xxxx'

    // 加密函数
    const encrypt = (value) => {
        const enc = new Encrypt();
        enc.setPublicKey(PUBLIC_KEY);
        value = Base64.encode(value)
        return enc.encryptLong(value)
    }

    // 解密函数
    const decrypt = (value) => {
        const enc = new Encrypt();
        enc.setPrivateKey(PRIVATE_KEY);
        let decrypt = enc.decryptLong(value);
        return Base64.decode(decrypt)
    }

    // 测试函数
    const test = () => {

        let startTime = new Date();
        // 使用设置公私钥
        const enc = new Encrypt();
        enc.setPublicKey(PUBLIC_KEY);
        enc.setPrivateKey(PRIVATE_KEY);

        // 一段长文本json
        let data = {
		    "code": 200,
		    "result": [
		        {"id": 1, "name": "张三", "age": 20 },
		        {"id": 2, "name": "李四", "age": 21 },
		    ]
		};
        data = JSON.stringify(data);
        let encrypted = enc.encryptLong(data);
        let endTime = new Date();
        console.log("加密后数据:%o", encrypted);
        console.log("加密时间" + (endTime - startTime) + "ms");
        //使用私钥解密
        let uncrypted = enc.decryptLong(encrypted);
        console.log("解密后数据:%o", uncrypted);
    }

    return {
        decrypt,
        encrypt,
        test,
    };

};
const RSA = RSAUtil();
export {RSA}

    /** RSA最大加密明文大小 */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /** RSA最大解密密文大小 */
    private static final int MAX_DECRYPT_BLOCK = 128;
    
    /**
     * @return {@code byte[] }
     * @description: 加密
     * @param: [data, publicKey]
     * @author: BrownSugar
     * @date: 2025-01-10 06:30:57
     **/
    public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        // 对数据加密
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

  /**
     * @return {@code byte[] }
     * @description: 解密
     * @param: [data, privateKey]
     * @author: BrownSugar
     * @date: 2025-01-10 06:31:04
     **/
    public static byte[] decryptByPrivateKey(byte[] data, String privateKey) throws Exception {
        // 得到私钥
        byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes());
        PKCS8EncodedKeySpec pKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key key = keyFactory.generatePrivate(pKCS8EncodedKeySpec);
        // 解密数据
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        // SealedObject obj = new SealedObject(data, cipher);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解�?
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        //byte[] messageBytes = (byte[]) obj.getObject(cipher);
        return decryptedData;
    }
   /**
     * @Description: 构建RSA密钥对
     * @Param: []
     * @Return: RsaKeyPair
     * @Author: BrownSugar
     * @Date: 2023-03-03 10:55:07
     **/
    public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
		// keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
        String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
        return new RsaKeyPair(publicKeyString, privateKeyString);
    }
三、总结
特点AESRSA
加密类型对称加密非对称加密
密钥长度128位、192位、256位2048位、4096位
安全性高,难以破解高,但需要更长的密钥
效率高,适合大量数据低,适合小数据传输
应用场景数据加密、通信加密、数据存储加密密钥交换、数字签名

总结:AES和RSA是目前最为常用的两种加密算法。AES适用于大规模数据的加密和解密,而RSA适用于数字签名和密钥协商等场景。在实际应用中,通常将两者结合使用,利用RSA的安全性进行密钥交换,利用AES的高效性进行数据加密。

### CentOS 镜像中 README 文件的作用 README 文件通常作为文档的一部分,在操作系统或软件包的分发过程中起到指导说明的作用。对于 CentOS 的镜像而言,其 README 文件的主要意义在于提供关于该版本的操作系统的关键信息以及安装指南。 #### 1. 提供版本信息 README 文件会明确指出当前镜像是哪个具体版本的 CentOS,例如 `CentOS Linux release 7.9.2009 (Core)`[^1]。这有助于用户确认所下载的是正确的发行版,并了解与其兼容的硬件软件环境。 #### 2. 描述安装前准备事项 在实际部署之前,用户可能需要完成一些必要的准备工作,比如安装工具 Git 或者其他依赖项。这些内容往往会在 README 中有所提及,帮助新手快速上手。 #### 3. 解决常见问题 针对可能出现的问题,如文件上传验证通过后的反馈机制——返回文件名表示成功[^2];或者如何正确配置服务端口映射等复杂场景下的解决方案也可能被记录下来以便查阅。 #### 4. 列举第三方库源地址 有时为了扩展功能,官方文档还会给出获取额外资源的方法论实例:“`wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz`” 就是用来示范怎样从外部站点拉取所需组件的例子之一[^3]。 #### 5. 展示高级设置教程 除了基本操作外,更深入的技术细节也会包含其中,例如为了让 NVM 成为全局变量而修改特定路径下的脚本文件 `/etc/profile.d/nvm.sh` [^4] ,或者是利用 FTP 协议传输大容量数据时推荐采用 Binary Mode 来保持文件完整性[^5]。 综上所述,README 不仅是一个简单的介绍性文本,更是连接开发者与最终用户的桥梁,它承载着丰富的背景资料技术支持,使得整个安装过程更加顺畅高效。 ```bash # 示例命令展示如何查看本地是否存在类似的 readme 文档 ls /path/to/your/downloaded/image/*.txt | grep -i "readme" cat /path/to/found/readme.txt ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值