• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Encryption and Decryption with an AES Symmetric Key (CBC Mode) (ArkTS)
2
3<!--Kit: Crypto Architecture Kit-->
4<!--Subsystem: Security-->
5<!--Owner: @zxz--3-->
6<!--Designer: @lanming-->
7<!--Tester: @PAFT-->
8<!--Adviser: @zengyawen-->
9
10For details about the algorithm specifications, see [Symmetric Key Encryption and Decryption Algorithm Specifications: AES](crypto-sym-encrypt-decrypt-spec.md#aes).
11
12**Encryption**
13
141. Call [cryptoFramework.createSymKeyGenerator](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatesymkeygenerator) and [SymKeyGenerator.generateSymKey](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatesymkey-1) to generate a 128-bit AES symmetric key (**SymKey**).
15
16   In addition to the example in this topic, [AES](crypto-sym-key-generation-conversion-spec.md#aes) and [Randomly Generating a Symmetric Key](crypto-generate-sym-key-randomly.md) may help you better understand how to generate an AES symmetric key. Note that the input parameters in the reference documents may be different from those in the example below.
17
182. Call [cryptoFramework.createCipher](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatecipher) with the string parameter **'AES128|CBC|PKCS7'** to create a **Cipher** instance for encryption. The key type is **AES128**, block cipher mode is **CBC**, and the padding mode is **PKCS7**.
19
203. Call [Cipher.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-1) to initialize the **Cipher** instance. In the **Cipher.init** API, set **opMode** to **CryptoMode.ENCRYPT_MODE** (encryption), **key** to **SymKey** (the key for encryption), and **params** to **IvParamsSpec** corresponding to the CBC mode.
21
224. To encrypt a small amount of data, simply call [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1).
23
24**Decryption**
25
261. Call [cryptoFramework.createCipher](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatecipher) with the string parameter **'AES128|CBC|PKCS7'** to create a **Cipher** instance for decryption. The key type is **AES128**, block cipher mode is **CBC**, and the padding mode is **PKCS7**.
27
282. Call [Cipher.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-1) to initialize the **Cipher** instance. In the **Cipher.init** API, set **opMode** to **CryptoMode.DECRYPT_MODE** (decryption), **key** to **SymKey** (the key for decryption), and **params** to **IvParamsSpec** corresponding to the CBC mode.
29
303. To decrypt a small amount of data, simply call [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1).
31
32- Example (using asynchronous APIs):
33
34  ```ts
35  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
36  import { buffer } from '@kit.ArkTS';
37
38  function generateRandom(len: number) {
39    let rand = cryptoFramework.createRandom();
40    let generateRandSync = rand.generateRandomSync(len);
41    return generateRandSync;
42  }
43
44  function genIvParamsSpec() {
45    let ivBlob = generateRandom(16);
46    let ivParamsSpec: cryptoFramework.IvParamsSpec = {
47      algName: "IvParamsSpec",
48      iv: ivBlob
49    };
50    return ivParamsSpec;
51  }
52  let iv = genIvParamsSpec();
53  // Encrypt the message.
54  async function encryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
55    let cipher = cryptoFramework.createCipher('AES128|CBC|PKCS7');
56    await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, iv);
57    let cipherData = await cipher.doFinal(plainText);
58    return cipherData;
59  }
60  // Decrypt the message.
61  async function decryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
62    let decoder = cryptoFramework.createCipher('AES128|CBC|PKCS7');
63    await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, iv);
64    let decryptData = await decoder.doFinal(cipherText);
65    return decryptData;
66  }
67
68  async function genSymKeyByData(symKeyData: Uint8Array) {
69    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
70    let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
71    let symKey = await aesGenerator.convertKey(symKeyBlob);
72    console.info('convertKey success');
73    return symKey;
74  }
75
76  async function aesCBC() {
77    try {
78      let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]);
79      let symKey = await genSymKeyByData(keyData);
80      let message = "This is a test";
81      let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
82      let encryptText = await encryptMessagePromise(symKey, plainText);
83      let decryptText = await decryptMessagePromise(symKey, encryptText);
84      if (plainText.data.toString() === decryptText.data.toString()) {
85        console.info('decrypt ok');
86        console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8'));
87      } else {
88        console.error('decrypt failed');
89      }
90    } catch (error) {
91      console.error(`AES CBC "${error}", error code: ${error.code}`);
92    }
93  }
94  ```
95
96- Example (using synchronous APIs):
97
98  ```ts
99  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
100  import { buffer } from '@kit.ArkTS';
101
102  function generateRandom(len: number) {
103    let rand = cryptoFramework.createRandom();
104    let generateRandSync = rand.generateRandomSync(len);
105    return generateRandSync;
106  }
107
108  function genIvParamsSpec() {
109    let ivBlob = generateRandom(16);
110    let ivParamsSpec: cryptoFramework.IvParamsSpec = {
111      algName: "IvParamsSpec",
112      iv: ivBlob
113    };
114    return ivParamsSpec;
115  }
116  let iv = genIvParamsSpec();
117  // Encrypt the message.
118  function encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
119    let cipher = cryptoFramework.createCipher('AES128|CBC|PKCS7');
120    cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, iv);
121    let cipherData = cipher.doFinalSync(plainText);
122    return cipherData;
123  }
124  // Decrypt the message.
125  function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
126    let decoder = cryptoFramework.createCipher('AES128|CBC|PKCS7');
127    decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, iv);
128    let decryptData = decoder.doFinalSync(cipherText);
129    return decryptData;
130  }
131
132  function genSymKeyByData(symKeyData: Uint8Array) {
133    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
134    let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
135    let symKey = aesGenerator.convertKeySync(symKeyBlob);
136    console.info('convertKeySync success');
137    return symKey;
138  }
139
140  function main() {
141    try {
142      let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]);
143      let symKey = genSymKeyByData(keyData);
144      let message = "This is a test";
145      let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
146      let encryptText = encryptMessage(symKey, plainText);
147      let decryptText = decryptMessage(symKey, encryptText);
148      if (plainText.data.toString() === decryptText.data.toString()) {
149        console.info('decrypt ok');
150        console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8'));
151      } else {
152        console.error('decrypt failed');
153      }
154    } catch (error) {
155      console.error(`AES CBC "${error}", error code: ${error.code}`);
156    }
157  }
158  ```
159