Encryption and Decryption with a ChaCha20 Symmetric Key Pair (ArkTS)
The Crypto framework supports this algorithm since API version 22.
For details about the algorithm specifications, see ChaCha20.
How to Develop
Creating an Object
Call cryptoFramework.createSymKeyGenerator and SymKeyGenerator.generateSymKey to generate a symmetric key (SymKey) using ChaCha20.
For details about how to generate a ChaCha20 symmetric key, see the following example. To learn more, see Symmetric Key Generation and Conversion Specifications: ChaCha20 and Randomly Generating a Symmetric Key. There may be differences between the input parameters in the reference documents and those in the following example.
Encryption
-
Call cryptoFramework.createCipher and specify the string parameter 'ChaCha20' to create a Cipher instance of the symmetric key for encryption.
-
Call Cipher.init to initialize the Cipher instance. Specifically, set the mode to cryptoFramework.CryptoMode.ENCRYPT_MODE (encryption), key to SymKey (the key for encryption), and parameter to IvParamsSpec.
-
Call Cipher.update to pass in the data to be encrypted (plaintext).
-
Call Cipher.doFinal to obtain the encrypted data.
NOTE
If data has been passed in by Cipher.update, pass in null in the data parameter of Cipher.doFinal.
The output of Cipher.doFinal may be null. To avoid exceptions, always check whether the result is null before accessing specific data.
Decryption
-
Call cryptoFramework.createCipher and specify the string parameter 'ChaCha20' to create a Cipher instance of the symmetric key for decryption.
-
Call Cipher.init to initialize the Cipher instance. Specifically, set the mode to cryptoFramework.CryptoMode.DECRYPT_MODE (decryption), key to SymKey (the key for decryption), and parameter to IvParamsSpec.
-
Call Cipher.update to pass in the data to be decrypted (ciphertext).
-
Call Cipher.doFinal to obtain the decrypted data.
-
Example (using asynchronous APIs):
import { cryptoFramework } from '@kit.CryptoArchitectureKit'; import { buffer } from '@kit.ArkTS'; function generateRandom(len: number) { let rand = cryptoFramework.createRandom(); let generateRandSync = rand.generateRandomSync(len); return generateRandSync; } function genIvParamsSpec() { let ivBlob = generateRandom(16); let ivParamsSpec: cryptoFramework.IvParamsSpec = { algName: 'IvParamsSpec', iv: ivBlob }; return ivParamsSpec; } let ivSpec = genIvParamsSpec(); // Encrypt the message. async function encryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) { let cipher = cryptoFramework.createCipher('ChaCha20'); await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, ivSpec); let encryptData = await cipher.doFinal(plainText); return encryptData; } // Decrypt the message. async function decryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) { let decoder = cryptoFramework.createCipher('ChaCha20'); await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, ivSpec); let decryptData = await decoder.doFinal(cipherText); return decryptData; } async function genSymKeyByData(symKeyData: Uint8Array) { let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; let chacha20Generator = cryptoFramework.createSymKeyGenerator('ChaCha20'); let symKey = await chacha20Generator.convertKey(symKeyBlob); console.info('convertKey result: success.'); return symKey; } async function main() { try { let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159, 83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); let symKey = await genSymKeyByData(keyData); let message = 'This is a test'; let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }; let encryptText = await encryptMessagePromise(symKey, plainText); let decryptText = await decryptMessagePromise(symKey, encryptText); if (plainText.data.toString() === decryptText.data.toString()) { console.info('decrypt ok.'); console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8')); } else { console.error('decrypt failed.'); } } catch (error) { console.error(`decrypt failed: errCode: ${error.code}, message: ${error.message}`); } } -
Example (using synchronous APIs):
import { cryptoFramework } from '@kit.CryptoArchitectureKit'; import { buffer } from '@kit.ArkTS'; function generateRandom(len: number) { let rand = cryptoFramework.createRandom(); let generateRandSync = rand.generateRandomSync(len); return generateRandSync; } function genIvParamsSpec() { let ivBlob = generateRandom(16); let ivParamsSpec: cryptoFramework.IvParamsSpec = { algName: 'IvParamsSpec', iv: ivBlob }; return ivParamsSpec; } let ivSpec = genIvParamsSpec(); // Encrypt the message. function encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) { let cipher = cryptoFramework.createCipher('ChaCha20'); cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, ivSpec); let encryptData = cipher.doFinalSync(plainText); return encryptData; } // Decrypt the message. function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) { let decoder = cryptoFramework.createCipher('ChaCha20'); decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, ivSpec); let decryptData = decoder.updateSync(cipherText); return decryptData; } function genSymKeyByData(symKeyData: Uint8Array) { let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; let chacha20Generator = cryptoFramework.createSymKeyGenerator('ChaCha20'); let symKey = chacha20Generator.convertKeySync(symKeyBlob); console.info('convertKeySync result: success.'); return symKey; } function main() { try { let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159, 83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); let symKey = genSymKeyByData(keyData); let message = 'This is a test'; let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }; let encryptText = encryptMessage(symKey, plainText); let decryptText = decryptMessage(symKey, encryptText); if (plainText.data.toString() === decryptText.data.toString()) { console.info('decrypt ok.'); console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8')); } else { console.error('decrypt failed.'); } } catch (error) { console.error(`decrypt failed: errCode: ${error.code}, message: ${error.message}`); } }