> ## 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

> Utility class for RSA public key encryption and decryption

## Overview

`RSAUtils` is a utility class that implements RSA public key encryption and decryption, using asymmetric encryption algorithms to ensure data transmission security. In API communication, it is used to encrypt sensitive business data for transmission and decrypt encrypted data returned from the server.

## Code Examples

<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 public key encryption/decryption utility class
  * <p>
  * Provides asymmetric encryption and decryption based on public key,
  * suitable for encrypted data transmission in API communication.
  */
  public class RSAUtils {
    // RSA encryption maximum block size (unit: bytes)
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /**
     * Encrypt data using public key
     *
     * @param data Original binary data
     * @param publicKey Base64 encoded public key string
     * @return Encrypted binary data
     *
     * Usage scenario: Encrypt business data before sending API requests.
     * Automatically handles chunked encryption of large data (117 bytes/chunk).
     *
     * Example:
     * byte[] encrypted = RSAUtils.encryptByPublicKey(
     *     jsonData.getBytes(),
     *     "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ..."
     * );
     */
    public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
        // 1. Base64 decode public key
        byte[] keyBytes = Base64Util.decodeString(publicKey);

        // 2. Generate public key object
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicK = keyFactory.generatePublic(
            new X509EncodedKeySpec(keyBytes)
        );

        // 3. Create and initialize cipher
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicK);

        // 4. Chunked encryption for large data
        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();
    }

    /**
     * Decrypt data using public key
     *
     * @param encryptedData Encrypted binary data
     * @param publicKey Base64 encoded public key string
     * @return Decrypted original binary data
     *
     * Usage scenario: Decrypt encrypted data returned from APIs.
     * Suitable for one-time decryption of small data chunks.
     *
     * Example:
     * byte[] decrypted = RSAUtils.decryptByPublicKey(
     *     encryptedBytes,
     *     "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ..."
     * );
     */
    public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {

        final int MAX_DECRYPT_BLOCK = 128;

        // 1. Base64 decode public key
        byte[] keyBytes = Base64Util.decodeString(publicKey);

        // 2. Generate public key object
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicK = keyFactory.generatePublic(
            new X509EncodedKeySpec(keyBytes)
        );

        // 3. Create and initialize decrypter
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicK);

        // 4. One-time decryption (suitable for small data)
        // return cipher.doFinal(encryptedData);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // Decrypt data in segments
        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 Public Key Encryption/Decryption Utility Class
  *
  * Provides asymmetric encryption and decryption capabilities based on public keys,
  * suitable for secure data transmission in API communications.
  */
  class RSAUtils {
    // Maximum block size for RSA encryption (in bytes)
    static MAX_ENCRYPT_BLOCK = 117;

    /**
     * Encrypts data using a public key
     * @param {Buffer} data - Raw binary data to be encrypted
     * @param {string} publicKey - Base64 encoded public key string
     * @returns {Buffer} Encrypted binary data
     *
     * Usage scenario: Encrypts business data before sending API requests.
     * Automatically handles large data segmentation (117 bytes per block).
     */
    static encryptByPublicKey(data, publicKey) {
        try {
            // 1. Convert Base64 public key to PEM format
            const pemKey = `-----BEGIN PUBLIC KEY-----\n${publicKey}\n-----END PUBLIC KEY-----`;

            // 2. Generate public key object
            const key = crypto.createPublicKey(pemKey);

            // 3. Create and initialize encryptor
            const encryptedParts = [];
            const buffer = Buffer.from(data);
            let offset = 0;
            const inputLen = buffer.length;

            // 4. Segment and encrypt large data
            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 encryption failed: ${error.message}`);
        }
    }

    /**
     * Decrypts data using a public key
     * @param {Buffer} encryptedData - Encrypted binary data
     * @param {string} publicKey - Base64 encoded public key string
     * @returns {Buffer} Decrypted raw binary data
     *
     * Usage scenario: Decrypts encrypted data returned from API responses.
     * Automatically handles large data segmentation (128 bytes per block).
     */
    static decryptByPublicKey(encryptedData, publicKey) {
        try {
            // 1. Convert Base64 public key to PEM format
            const pemKey = `-----BEGIN PUBLIC KEY-----\n${publicKey}\n-----END PUBLIC KEY-----`;

            // 2. Generate public key object
            const key = crypto.createPublicKey(pemKey);

            // 3. Create and initialize decryptor
            const decryptedParts = [];
            const buffer = Buffer.from(encryptedData);
            let offset = 0;
            const inputLen = buffer.length;
            const MAX_DECRYPT_BLOCK = 128;

            // 4. Segment and decrypt data
            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 decryption failed: ${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 encryption maximum block size (unit: bytes)
  MAX_ENCRYPT_BLOCK = 117

  @staticmethod
  def encrypt_by_public_key(data: bytes, public_key_str: str) -> bytes:
      """
      Encrypt data using public key
      @param data: Original binary data
      @param public_key_str: Base64 encoded public key string
      @return: Encrypted binary data

      Usage scenario: Encrypt business data before sending API requests
      Automatically handles chunked encryption of large data (117 bytes/chunk)
      """
      # 1. Base64 decode public key
      public_key_der = base64.b64decode(public_key_str)

      # 2. Load public key object
      public_key = serialization.load_der_public_key(
          public_key_der,
          backend=default_backend()
      )

      # 3. Chunked encryption
      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:
      """
      Decrypt data using public key
      @param encrypted_data: Encrypted binary data
      @param public_key_str: Base64 encoded public key string
      @return: Decrypted original binary data

      Usage scenario: Decrypt encrypted data returned from APIs
      Suitable for one-time decryption of small data chunks
      """
      # 1. Base64 decode public key
      public_key_der = base64.b64decode(public_key_str)

      # 2. Load public key object
      public_key = serialization.load_der_public_key(
          public_key_der,
          backend=default_backend()
      )

      # 3. One-time decryption
      return public_key.decrypt(
          encrypted_data,
          padding.OAEP(
              mgf=padding.MGF1(algorithm=hashes.SHA256()),
              algorithm=hashes.SHA256(),
              label=None
          )
      )

  # Usage example
  if __name__ == "__main__":
  # Simulate public key string
  public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ..."

  # Data to encrypt
  data = b"Sensitive data 12345"

  try:
      # Encryption
      encrypted = RSAUtils.encrypt_by_public_key(data, public_key)
      print("Encryption result:", base64.b64encode(encrypted).decode())

      # Decryption
      decrypted = RSAUtils.decrypt_by_public_key(encrypted, public_key)
      print("Decryption result:", decrypted.decode())
  except Exception as e:
      print("RSA operation failed:", e)
  ```
</CodeGroup>
