> ## Documentation Index
> Fetch the complete documentation index at: https://waasapi.uuwallet.com/llms.txt
> Use this file to discover all available pages before exploring further.

# RSAUtils

> 用于RSA公钥加密和解密的工具类

## 概述

`RSAUtils` 是实现RSA公钥加密和解密的工具类，采用非对称加密算法保障数据传输安全。在API通信中，用于对敏感业务数据进行加密传输，以及解密服务器返回的加密数据。

## 代码实例

<CodeGroup>
  ```java RSAUtils.java theme={null}
  import java.io.ByteArrayOutputStream;
  import java.util.Base64;
  import javax.crypto.Cipher;
  import java.security.Key;
  import java.security.KeyFactory;
  import java.security.spec.X509EncodedKeySpec;

  /**
  * RSA公钥加解密工具类
  * <p>
  * 提供基于公钥的非对称加密解密功能，
  * 适用于API通信中的数据加密传输。
  */
  public class RSAUtils {
    // RSA加密最大块大小（单位：字节）
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /**
     * 使用公钥加密数据
     *
     * @param data 原始二进制数据
     * @param publicKey Base64编码的公钥字符串
     * @return 加密后的二进制数据
     *
     * 使用场景：在发送API请求前，加密业务数据。
     * 自动处理大数据的分段加密（117字节/块）。
     *
     * 示例：
     * byte[] encrypted = RSAUtils.encryptByPublicKey(
     *     jsonData.getBytes(),
     *     "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ..."
     * );
     */
    public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
        // 1. Base64解码公钥
        byte[] keyBytes = Base64Util.decodeString(publicKey);

        // 2. 生成公钥对象
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicK = keyFactory.generatePublic(
                new X509EncodedKeySpec(keyBytes)
        );

        // 3. 创建并初始化加密器
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicK);

        // 4. 分段加密处理大数据
        int inputLen = data.length;
        int offset = 0;
        java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();

        while (inputLen - offset > 0) {
            int blockSize = Math.min(inputLen - offset, MAX_ENCRYPT_BLOCK);
            byte[] encryptedBlock = cipher.doFinal(data, offset, blockSize);
            out.write(encryptedBlock, 0, encryptedBlock.length);
            offset += blockSize;
        }

        return out.toByteArray();
    }

    /**
     * 使用公钥解密数据
     *
     * @param encryptedData 加密后的二进制数据
     * @param publicKey Base64编码的公钥字符串
     * @return 解密后的原始二进制数据
     *
     * 使用场景：解密API返回的加密数据。
     * 适用于小数据块的一次性解密操作。
     *
     * 示例：
     * byte[] decrypted = RSAUtils.decryptByPublicKey(
     *     encryptedBytes,
     *     "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ..."
     * );
     */
    public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {

        final int MAX_DECRYPT_BLOCK = 128;
        // 1. Base64解码公钥
        byte[] keyBytes = Base64Util.decodeString(publicKey);

        // 2. 生成公钥对象
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicK = keyFactory.generatePublic(
                new X509EncodedKeySpec(keyBytes)
        );

        // 3. 创建并初始化解密器
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicK);
       // 4. 一次性解密（适合小数据）
       //return cipher.doFinal(encryptedData);
        int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }
  }
  ```

  ```javascript RSAUtils.js theme={null}
  const crypto = require('crypto');
  const Base64Util = require('./Base64Util');

  /**
  * RSA 公钥加解密工具类
  *
  * 提供基于公钥的非对称加密解密功能，
  * 适用于 API 通信中的数据加密传输。
  */
  class RSAUtils {
    // RSA 加密最大块大小（单位：字节）
    static MAX_ENCRYPT_BLOCK = 117;

    /**
     * 使用公钥加密数据
     * @param {Buffer} data - 原始二进制数据
     * @param {string} publicKey - Base64 编码的公钥字符串
     * @returns {Buffer} 加密后的二进制数据
     *
     * 使用场景：在发送 API 请求前，加密业务数据。
     * 自动处理大数据的分段加密（117 字节/块）。
     */
    static encryptByPublicKey(data, publicKey) {
        try {
            // 1. 将 Base64 公钥转换为 PEM 格式
            const pemKey = `-----BEGIN PUBLIC KEY-----\n${publicKey}\n-----END PUBLIC KEY-----`;

            // 2. 生成公钥对象
            const key = crypto.createPublicKey(pemKey);

            // 3. 创建并初始化加密器
            const encryptedParts = [];
            const buffer = Buffer.from(data);
            let offset = 0;
            const inputLen = buffer.length;

            // 4. 分段加密处理大数据
            while (offset < inputLen) {
                const blockSize = Math.min(inputLen - offset, RSAUtils.MAX_ENCRYPT_BLOCK);
                const chunk = buffer.slice(offset, offset + blockSize);
                const encryptedChunk = crypto.publicEncrypt({
                    key: key,
                    padding: crypto.constants.RSA_PKCS1_PADDING
                }, chunk);
                encryptedParts.push(encryptedChunk);
                offset += blockSize;
            }

            return Buffer.concat(encryptedParts);
        } catch (error) {
            throw new Error(`RSA 加密失败: ${error.message}`);
        }
    }

    /**
     * 使用公钥解密数据
     * @param {Buffer} encryptedData - 加密后的二进制数据
     * @param {string} publicKey - Base64 编码的公钥字符串
     * @returns {Buffer} 解密后的原始二进制数据
     *
     * 使用场景：解密 API 返回的加密数据。
     * 自动处理大数据的分段解密（128 字节/块）。
     */
    static decryptByPublicKey(encryptedData, publicKey) {
        try {
            // 1. 将 Base64 公钥转换为 PEM 格式
            const pemKey = `-----BEGIN PUBLIC KEY-----\n${publicKey}\n-----END PUBLIC KEY-----`;

            // 2. 生成公钥对象
            const key = crypto.createPublicKey(pemKey);

            // 3. 创建并初始化解密器
            const decryptedParts = [];
            const buffer = Buffer.from(encryptedData);
            let offset = 0;
            const inputLen = buffer.length;
            const MAX_DECRYPT_BLOCK = 128;

            // 4. 分段解密
            while (offset < inputLen) {
                const blockSize = Math.min(inputLen - offset, MAX_DECRYPT_BLOCK);
                const chunk = buffer.slice(offset, offset + blockSize);
                const decryptedChunk = crypto.publicDecrypt({
                    key: key,
                    padding: crypto.constants.RSA_PKCS1_PADDING
                }, chunk);
                decryptedParts.push(decryptedChunk);
                offset += blockSize;
            }

            return Buffer.concat(decryptedParts);
        } catch (error) {
            throw new Error(`RSA 解密失败: ${error.message}`);
        }
    }
  }

  module.exports = RSAUtils;
  ```

  ```python RSAUtils.py theme={null}
  import base64
  from cryptography.hazmat.primitives import serialization
  from cryptography.hazmat.primitives.asymmetric import padding
  from cryptography.hazmat.backends import default_backend

  class RSAUtils:
    # RSA加密最大块大小（单位：字节）
    MAX_ENCRYPT_BLOCK = 117

    @staticmethod
    def encrypt_by_public_key(data: bytes, public_key_str: str) -> bytes:
        """
        使用公钥加密数据
        @param data: 原始二进制数据
        @param public_key_str: Base64编码的公钥字符串
        @return: 加密后的二进制数据

        使用场景：在发送API请求前，加密业务数据
        自动处理大数据的分段加密（117字节/块）
        """
        # 1. Base64解码公钥
        public_key_der = base64.b64decode(public_key_str)

        # 2. 加载公钥对象
        public_key = serialization.load_der_public_key(
            public_key_der,
            backend=default_backend()
        )

        # 3. 分段加密
        offset = 0
        encrypted_chunks = []
        while offset < len(data):
            block = data[offset:offset + RSAUtils.MAX_ENCRYPT_BLOCK]
            encrypted_chunk = public_key.encrypt(
                block,
                padding.OAEP(
                    mgf=padding.MGF1(algorithm=hashes.SHA256()),
                    algorithm=hashes.SHA256(),
                    label=None
                )
            )
            encrypted_chunks.append(encrypted_chunk)
            offset += len(block)

        return b''.join(encrypted_chunks)

    @staticmethod
    def decrypt_by_public_key(encrypted_data: bytes, public_key_str: str) -> bytes:
        """
        使用公钥解密数据
        @param encrypted_data: 加密后的二进制数据
        @param public_key_str: Base64编码的公钥字符串
        @return: 解密后的原始二进制数据

        使用场景：解密API返回的加密数据
        适用于小数据块的一次性解密操作
        """
        # 1. Base64解码公钥
        public_key_der = base64.b64decode(public_key_str)

        # 2. 加载公钥对象
        public_key = serialization.load_der_public_key(
            public_key_der,
            backend=default_backend()
        )

        # 3. 一次性解密
        return public_key.decrypt(
            encrypted_data,
            padding.OAEP(
                mgf=padding.MGF1(algorithm=hashes.SHA256()),
                algorithm=hashes.SHA256(),
                label=None
            )
        )

  # 使用示例
  if __name__ == "__main__":
    # 模拟公钥字符串
    public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ..."

    # 待加密数据
    data = b"敏感数据12345"

    try:
        # 加密
        encrypted = RSAUtils.encrypt_by_public_key(data, public_key)
        print("加密结果:", base64.b64encode(encrypted).decode())

        # 解密
        decrypted = RSAUtils.decrypt_by_public_key(encrypted, public_key)
        print("解密结果:", decrypted.decode())
    except Exception as e:
        print("RSA操作失败:", e)
  ```
</CodeGroup>
