DEV Community

HarmonyOS
HarmonyOS

Posted on

RSA Text Encryption & Decryption with CryptoArchitectureKit

Read the original article:RSA Text Encryption & Decryption with CryptoArchitectureKit

Requirement Description

This document outlines a reusable RSA encryption and decryption service using the asymmetric key model in HarmonyOS. It leverages UniversalKeystoreKit for secure key management and CryptoArchitectureKit for cryptographic operations. The implementation uses Base64 encoding for safe string transport and supports PKCS1 v1.5 padding.

Background Knowledge

Secure RSA key generation and storage via Keystore.Asymmetric encryption with public/private key pair.Base64-encoded ciphertext for safe string transport.Handles asynchronous operations with callbacks.Easily integrable into any HarmonyOS application

Implementation Steps

Key and Algorithm Setup

const RSA_KEY_ALIAS: string = 'rsa_key_alias'; // Alias used to store/retrieve key pair
const RSA_ALGO: string = 'RSA2048|PKCS1_V1_5'; // RSA algorithm and padding mode
Enter fullscreen mode Exit fullscreen mode

Key Generation

generateKeyPair(callback: (success: boolean) => void) {
  const genParam: GenerateKeyOption = {
    alias: RSA_KEY_ALIAS,
    algorithm: 'RSA',
    keySize: 2048,
    isAuthenticationRequired: false
  };

  keystore.generateKey(genParam, (err) => {
    if (err) {
      console.error('RSA key generation failed:', err.code);
      callback(false);
    } else {
      callback(true);
    }
  });
}Copy codeCopy code
Enter fullscreen mode Exit fullscreen mode

This method creates a 2048-bit RSA key pair stored securely in the Keystore.

Encryption

rsaEncrypt(message: string, callback: (value: string) => void) {
  const base64 = new util.Base64Helper();
  const inputBytes = stringToUint8Array(message);
  const inputData = { data: inputBytes };

  cryptoFramework.rsaEncrypt(RSA_KEY_ALIAS, RSA_ALGO, inputData, (err, output) => {
    if (err) {
      console.error('RSA Encrypt failed:', err.code);
      callback('');
    } else {
      const encrypted = base64.encodeToStringSync(output.data);
      console.log('[Encrypt] Result:', encrypted);
      callback(encrypted);
    }
  });
}
Enter fullscreen mode Exit fullscreen mode

Decryption

rsaDecrypt(encryptedText: string, callback: (value: string) => void) {
  const base64 = new util.Base64Helper();
  const decoded = base64.decodeSync(encryptedText);
  const inputData = { data: decoded };

  cryptoFramework.rsaDecrypt(RSA_KEY_ALIAS, RSA_ALGO, inputData, (err, output) => {
    if (err) {
      console.error('RSA Decrypt failed:', err.code);
      callback('');
    } else {
      const decrypted = uint8ArrayToString(output.data);
      console.log('[Decrypt] Result:', decrypted);
      callback(decrypted);
    }
  });
}
Enter fullscreen mode Exit fullscreen mode

Helper Functions

function stringToUint8Array(str: string): Uint8Array {
  const arr = new Uint8Array(str.length);
  for (let i = 0; i < str.length; i++) {
    arr[i] = str.charCodeAt(i);
  }
  return arr;
}

function uint8ArrayToString(arr: Uint8Array): string {
  let str = '';
  for (let i = 0; i < arr.length; i++) {
    str += String.fromCharCode(arr[i]);
  }
  return str;
}
Enter fullscreen mode Exit fullscreen mode

Code Snippet

cipherService: CipherService = new CipherService();

encryptText(plainText: string) {
  this.cipherService.rsaEncrypt(plainText, (encrypted) => {
    this.encryptedMessage = encrypted;
    console.info('Encrypted:', encrypted);
  });
}

decryptText(encryptedText: string) {
  this.cipherService.rsaDecrypt(encryptedText, (decrypted) => {
    this.decryptedMessage = decrypted;
    console.info('Decrypted:', decrypted);
  });
}
Enter fullscreen mode Exit fullscreen mode

Security Notes

RSA keys are securely stored and never exposed to the app layer.

Only the public key is used for encryption, while the private key remains protected in the system Keystore.

Always verify key generation before attempting encryption/decryption.

Written by Emrecan Karakaş

Top comments (0)