We use essential cookies for the website to function, as well as analytics cookies for analyzing and creating statistics of the website performance. To agree to the use of analytics cookies, click "Accept All". You can manage your preferences at any time by clicking "Cookie Settings" on the footer. More Information.

Only Essential Cookies
Accept All
GuidesSystemSecurityCrypto Architecture KitEncryption and DecryptionEncryption and Decryption DevelopmentEncryption and Decryption Using ECIES (ArkTS)

Encryption and Decryption Using ECIES (ArkTS)

The ECIES algorithm is supported since API version 26.0.0. It is an encryption algorithm based on elliptic curve cryptography.

Constraints

  • Key agreement algorithms ECC256, ECC384, and ECC521 are supported.
  • Among key derivation algorithms, only X963KDF is supported. Digest algorithms SHA-1, SHA-256, SHA-384, and SHA-512 are supported.
  • Symmetric encryption algorithms AES-128, AES-192, and AES-256 are supported.
  • Among block cipher modes, only GCM is supported.

Development Procedure

Encryption

  1. Call cryptoFramework.createAsyKeyGenerator and SymKeyGenerator.generateKeyPair to generate a key pair using the ECC algorithm.

  2. Call cryptoFramework.createKeyAgreement and KeyAgreement.generateSecret to perform key agreement based on the local private key (KeyPair.priKey) and peer public key (KeyPair.pubKey) and return the shared key.

  3. Call cryptoFramework.createKdf and Kdf.generateSecret to derive a key based on the shared key (Secret) using the X963KDF algorithm and return the derived key.

  4. Call cryptoFramework.createCipher with the string parameter 'AES128|GCM' to create a Cipher instance for encryption. The key type is AES-128, and the block cipher mode is GCM.

  5. 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 GcmParamsSpec corresponding to the GCM mode.

  6. Call Cipher.update to pass the data to be encrypted (plaintext).

  7. Call Cipher.doFinal to obtain the encrypted data.

  8. Obtain GcmParamsSpec.authTag as the authentication information for decryption.

Decryption

  1. Call cryptoFramework.createAsyKeyGenerator and SymKeyGenerator.generateKeyPair to generate a key pair using the ECC algorithm.

  2. Call cryptoFramework.createKeyAgreement and KeyAgreement.generateSecret to perform key agreement based on the local private key (KeyPair.priKey) and peer public key (KeyPair.pubKey) and return the shared key.

  3. Call cryptoFramework.createKdf and Kdf.generateSecret to derive a key based on the shared key (Secret) using the X963KDF algorithm and return the derived key.

  4. Call cryptoFramework.createCipher with the string parameter 'AES128|GCM' to create a Cipher instance for decryption. The key type is AES-128, and the block cipher mode is GCM.

  5. 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 GcmParamsSpec corresponding to the GCM mode.

  6. Call Cipher.update to pass the data to be decrypted (ciphertext).

  7. Call Cipher.doFinal to obtain the decrypted data.

Example Code

  • Example (using asynchronous APIs):

    Collapse
    Word wrap
    Dark theme
    Copy code
    1. import { cryptoFramework } from '@kit.CryptoArchitectureKit';
    2. import { buffer } from '@kit.ArkTS';
    3. namespace ECIES {
    4. function generateGcmParamsSpec(ivData: Uint8Array): cryptoFramework.GcmParamsSpec {
    5. let ivBlob: cryptoFramework.DataBlob = {
    6. data: ivData,
    7. };
    8. let rand: cryptoFramework.Random = cryptoFramework.createRandom();
    9. let aadBlob: cryptoFramework.DataBlob = rand.generateRandomSync(8);
    10. let tagBlob: cryptoFramework.DataBlob = rand.generateRandomSync(16);
    11. // Obtain the GCM authTag from the Cipher.doFinal result in encryption and fill it in the params parameter of Cipher.init in decryption.
    12. let gcmParams: cryptoFramework.GcmParamsSpec = {
    13. iv: ivBlob,
    14. aad: aadBlob,
    15. authTag: tagBlob,
    16. algName: 'GcmParamsSpec',
    17. };
    18. return gcmParams;
    19. }
    20. async function generateSecret(priKey: cryptoFramework.PriKey, pubKey: cryptoFramework.PubKey):
    21. Promise<cryptoFramework.DataBlob> {
    22. // EC key agreement.
    23. let agreement: cryptoFramework.KeyAgreement = cryptoFramework.createKeyAgreement('ECC256');
    24. let keyData: cryptoFramework.DataBlob = await agreement.generateSecret(priKey, pubKey);
    25. let infoData: Uint8Array = new Uint8Array(buffer.from('infostring', 'utf-8').buffer);
    26. let spec: cryptoFramework.X963KdfSpec = {
    27. algName: 'X963KDF',
    28. key: keyData.data,
    29. info: infoData,
    30. keySize: 32, // The first 16 bytes are used as the IV of AES-128, and the last 16 bytes are used as the key.
    31. };
    32. // Derive the key using X963KDF.
    33. let kdf = cryptoFramework.createKdf('X963KDF|SHA256');
    34. let secret = await kdf.generateSecret(spec);
    35. return secret;
    36. }
    37. async function generateSymKey(secret: cryptoFramework.DataBlob): Promise<cryptoFramework.SymKey> {
    38. let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES128');
    39. let keyData: cryptoFramework.DataBlob = {
    40. data: secret.data.slice(16),
    41. };
    42. let symKey: cryptoFramework.SymKey = await symKeyGenerator.convertKey(keyData);
    43. return symKey;
    44. }
    45. async function encrypt(symKey: cryptoFramework.SymKey, gcmParams: cryptoFramework.GcmParamsSpec,
    46. plainText: cryptoFramework.DataBlob): Promise<cryptoFramework.DataBlob> {
    47. // AES-GCM symmetric encryption
    48. let cipher: cryptoFramework.Cipher = cryptoFramework.createCipher('AES128|GCM');
    49. await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, gcmParams);
    50. let cipherText: cryptoFramework.DataBlob = await cipher.update(plainText);
    51. gcmParams.authTag = await cipher.doFinal(null);
    52. return cipherText;
    53. }
    54. async function decrypt(symKey: cryptoFramework.SymKey, gcmParams: cryptoFramework.GcmParamsSpec,
    55. cipherText: cryptoFramework.DataBlob): Promise<cryptoFramework.DataBlob> {
    56. // AES-GCM symmetric decryption.
    57. let cipher: cryptoFramework.Cipher = cryptoFramework.createCipher('AES128|GCM');
    58. await cipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, gcmParams);
    59. let plainText: cryptoFramework.DataBlob = await cipher.doFinal(cipherText);
    60. return plainText;
    61. }
    62. export async function doEciesTest(): Promise<string> {
    63. try {
    64. // Generate EC key pairs for ends A and B.
    65. let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator('ECC256');
    66. let keyPairA: cryptoFramework.KeyPair = asyKeyGenerator.generateKeyPairSync();
    67. let keyPairB: cryptoFramework.KeyPair = asyKeyGenerator.generateKeyPairSync();
    68. // Encryption at end A: private key of end A + public key of end B
    69. let secretA: cryptoFramework.DataBlob = await generateSecret(keyPairA.priKey, keyPairB.pubKey);
    70. let symKeyA: cryptoFramework.SymKey = await generateSymKey(secretA);
    71. let ivData: Uint8Array = secretA.data.slice(0, 16);
    72. let gcmParams: cryptoFramework.GcmParamsSpec = generateGcmParamsSpec(ivData);
    73. let message: string = 'This is a test message!!!';
    74. let plainText: cryptoFramework.DataBlob = {
    75. data: new Uint8Array(buffer.from(message, 'utf-8').buffer),
    76. };
    77. let cipherData: cryptoFramework.DataBlob = await encrypt(symKeyA, gcmParams, plainText);
    78. // Decryption at end B: private key of end B + public key of end A
    79. let secretB: cryptoFramework.DataBlob = await generateSecret(keyPairB.priKey, keyPairA.pubKey);
    80. let symKeyB: cryptoFramework.SymKey = await generateSymKey(secretB);
    81. let plainData: cryptoFramework.DataBlob = await decrypt(symKeyB, gcmParams, cipherData);
    82. console.info('doEciesTest success, message: ' + buffer.from(plainData.data).toString('utf-8'));
    83. return 'Success';
    84. } catch (error) {
    85. console.error(`doEciesTest failed, error: + ${JSON.stringify(error)}`);
    86. return 'Failed';
    87. }
    88. }
    89. }
  • Example (using synchronous APIs):

    Collapse
    Word wrap
    Dark theme
    Copy code
    1. import { cryptoFramework } from '@kit.CryptoArchitectureKit';
    2. import { buffer } from '@kit.ArkTS';
    3. namespace ECIES {
    4. function generateGcmParamsSpec(ivData: Uint8Array): cryptoFramework.GcmParamsSpec {
    5. let ivBlob: cryptoFramework.DataBlob = {
    6. data: ivData,
    7. };
    8. let rand: cryptoFramework.Random = cryptoFramework.createRandom();
    9. let aadBlob: cryptoFramework.DataBlob = rand.generateRandomSync(8);
    10. let tagBlob: cryptoFramework.DataBlob = rand.generateRandomSync(16);
    11. // Obtain the GCM authTag from the Cipher.doFinal result in encryption and fill it in the params parameter of Cipher.init in decryption.
    12. let gcmParams: cryptoFramework.GcmParamsSpec = {
    13. iv: ivBlob,
    14. aad: aadBlob,
    15. authTag: tagBlob,
    16. algName: 'GcmParamsSpec',
    17. };
    18. return gcmParams;
    19. }
    20. function generateSecret(priKey: cryptoFramework.PriKey, pubKey: cryptoFramework.PubKey):
    21. cryptoFramework.DataBlob {
    22. // EC key agreement.
    23. let agreement: cryptoFramework.KeyAgreement = cryptoFramework.createKeyAgreement('ECC256');
    24. let keyData: cryptoFramework.DataBlob = agreement.generateSecretSync(priKey, pubKey);
    25. let infoData: Uint8Array = new Uint8Array(buffer.from('infostring', 'utf-8').buffer);
    26. let spec: cryptoFramework.X963KdfSpec = {
    27. algName: 'X963KDF',
    28. key: keyData.data,
    29. info: infoData,
    30. keySize: 32, // The first 16 bytes are used as the IV of AES-128, and the last 16 bytes are used as the key.
    31. };
    32. // Derive the key using X963KDF.
    33. let kdf = cryptoFramework.createKdf('X963KDF|SHA256');
    34. let secret = kdf.generateSecretSync(spec);
    35. return secret;
    36. }
    37. function generateSymKey(secret: cryptoFramework.DataBlob): cryptoFramework.SymKey {
    38. let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES128');
    39. let keyData: cryptoFramework.DataBlob = {
    40. data: secret.data.slice(16),
    41. };
    42. let symKey: cryptoFramework.SymKey = symKeyGenerator.convertKeySync(keyData);
    43. return symKey;
    44. }
    45. function encrypt(symKey: cryptoFramework.SymKey, gcmParams: cryptoFramework.GcmParamsSpec,
    46. plainText: cryptoFramework.DataBlob): cryptoFramework.DataBlob {
    47. // AES-GCM symmetric encryption
    48. let cipher: cryptoFramework.Cipher = cryptoFramework.createCipher('AES128|GCM');
    49. cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, gcmParams);
    50. let cipherText: cryptoFramework.DataBlob = cipher.updateSync(plainText);
    51. gcmParams.authTag = cipher.doFinalSync(null);
    52. return cipherText;
    53. }
    54. function decrypt(symKey: cryptoFramework.SymKey, gcmParams: cryptoFramework.GcmParamsSpec,
    55. cipherText: cryptoFramework.DataBlob): cryptoFramework.DataBlob {
    56. // AES-GCM symmetric decryption.
    57. let cipher: cryptoFramework.Cipher = cryptoFramework.createCipher('AES128|GCM');
    58. cipher.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, gcmParams);
    59. let plainText: cryptoFramework.DataBlob = cipher.doFinalSync(cipherText);
    60. return plainText;
    61. }
    62. export function doEciesTest(): string {
    63. try {
    64. // Generate EC key pairs for ends A and B.
    65. let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator('ECC256');
    66. let keyPairA: cryptoFramework.KeyPair = asyKeyGenerator.generateKeyPairSync();
    67. let keyPairB: cryptoFramework.KeyPair = asyKeyGenerator.generateKeyPairSync();
    68. // Encryption at end A: private key of end A + public key of end B
    69. let secretA: cryptoFramework.DataBlob = generateSecret(keyPairA.priKey, keyPairB.pubKey);
    70. let symKeyA: cryptoFramework.SymKey = generateSymKey(secretA);
    71. let ivData: Uint8Array = secretA.data.slice(0, 16);
    72. let gcmParams: cryptoFramework.GcmParamsSpec = generateGcmParamsSpec(ivData);
    73. let message: string = 'This is a test message!!!';
    74. let plainText: cryptoFramework.DataBlob = {
    75. data: new Uint8Array(buffer.from(message, 'utf-8').buffer),
    76. };
    77. let cipherData: cryptoFramework.DataBlob = encrypt(symKeyA, gcmParams, plainText);
    78. // Decryption at end B: private key of end B + public key of end A
    79. let secretB: cryptoFramework.DataBlob = generateSecret(keyPairB.priKey, keyPairA.pubKey);
    80. let symKeyB: cryptoFramework.SymKey = generateSymKey(secretB);
    81. let plainData: cryptoFramework.DataBlob = decrypt(symKeyB, gcmParams, cipherData);
    82. console.info('doEciesTest success, message: ' + buffer.from(plainData.data).toString('utf-8'));
    83. return 'Success';
    84. } catch (error) {
    85. console.error(`doEciesTest failed, error: + ${JSON.stringify(error)}`);
    86. return 'Failed';
    87. }
    88. }
    89. }
Search in Guides
Enter a keyword.