• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Database Encryption (ArkTS)
2
3## When to Use
4
5OpenHarmony provides the database encryption capability to effectively protect the data stored in a database. Database encryption allows data to be stored and used in ciphertext, ensuring data confidentiality and integrity.
6
7The encrypted database can be accessed only using an API, and the database file cannot be opened in other ways. Whether a database is encrypted is set when the database is created, and the setting cannot be changed.
8
9Both KV stores and RDB stores support database encryption. For RDB stores, you can custom the encryption/decryption keys and other parameters.
10
11
12## Encrypting a KV Store
13
14When a KV store is created, the **encrypt** parameter in **options** specifies whether to encrypt it. The value **true** means to encrypt the KV store, and the value **false** (default) means the opposite.
15
16For details about the APIs, see [Distributed KV Store](../reference/apis-arkdata/js-apis-distributedKVStore.md).
17
18```ts
19import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
20import { hilog } from '@kit.PerformanceAnalysisKit';
21import { distributedKVStore } from '@kit.ArkData';
22import { BusinessError } from '@kit.BasicServicesKit';
23
24export default class EntryAbility extends UIAbility {
25  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
26    this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
27    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
28    let kvManager: distributedKVStore.KVManager | undefined = undefined;
29    let kvStore: distributedKVStore.SingleKVStore | undefined = undefined;
30    let context = this.context;
31    const kvManagerConfig: distributedKVStore.KVManagerConfig = {
32      context: context,
33      bundleName: 'com.example.datamanagertest',
34    }
35    try {
36      kvManager = distributedKVStore.createKVManager(kvManagerConfig);
37      console.info('Succeeded in creating KVManager.');
38    } catch (e) {
39      let error = e as BusinessError;
40      console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`);
41    }
42    if (kvManager !== undefined) {
43      kvManager = kvManager as distributedKVStore.KVManager;
44      try {
45        const options: distributedKVStore.Options = {
46          createIfMissing: true,
47          // Whether to encrypt the KV store.
48          encrypt: true,
49          backup: false,
50          autoSync: false,
51          kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
52          securityLevel: distributedKVStore.SecurityLevel.S3
53        };
54        kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', options, (err, store: distributedKVStore.SingleKVStore) => {
55          if (err) {
56            console.error(`Fail to get KVStore. Code:${err.code},message:${err.message}`);
57            return;
58          }
59          console.info('Succeeded in getting KVStore.');
60          kvStore = store;
61        });
62      } catch (e) {
63        let error = e as BusinessError;
64        console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);
65      }
66    }
67    if (kvStore !== undefined) {
68      kvStore = kvStore as distributedKVStore.SingleKVStore;
69      // Perform subsequent operations.
70      //...
71    }
72  }
73}
74```
75
76## Encrypting an RDB Store
77
78The **encrypt** property in [StoreConfig](../reference/apis-arkdata/arkts-apis-data-relationalStore-i.md#storeconfig) specifies whether to encrypt the RDB store. The value **true** means to encrypt the RDB store, and **false** means the opposite.
79
80If **encrypt** is **true**, you can set parameters such as the key and algorithm used for encryption/decryption in **cryptoParam** in ArkTS APIs.
81
82The **cryptoParam** setting involves the following scenarios:
83
84If **cryptoParam** is not set, the default configuration is used for database encryption and decryption.
85
86
87```ts
88import { UIAbility } from '@kit.AbilityKit';
89import { relationalStore } from '@kit.ArkData';
90import { BusinessError } from '@kit.BasicServicesKit';
91
92export default class EntryAbility extends UIAbility {
93  async onCreate(): Promise<void> {
94    let store: relationalStore.RdbStore | undefined = undefined;
95    let context = this.context;
96
97    try {
98      const STORE_CONFIG: relationalStore.StoreConfig = {
99        name: 'RdbTest.db',
100        securityLevel: relationalStore.SecurityLevel.S3,
101        encrypt: true
102      };
103      store = await relationalStore.getRdbStore(context, STORE_CONFIG);
104      console.info('Succeeded in getting RdbStore.');
105    } catch (e) {
106      const err = e as BusinessError;
107      console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
108    }
109  }
110}
111```
112
113If **cryptoParam** is set, the specified key and algorithm are used for database encryption and decryption.
114
115```ts
116import { UIAbility } from '@kit.AbilityKit';
117import { relationalStore } from '@kit.ArkData';
118import { BusinessError } from '@kit.BasicServicesKit';
119
120export default class EntryAbility extends UIAbility {
121  async onCreate(): Promise<void> {
122    let store: relationalStore.RdbStore | undefined = undefined;
123    let context = this.context;
124    // Initialize the key to be used.
125    let key = new Uint8Array(32);
126    for (let i = 0; i < 32; i++) {
127      key[i] = i;
128    }
129
130    // Initialize the encryption algorithm.
131    const CRYPTO_PARAM: relationalStore.CryptoParam = {
132      encryptionKey: key, // (Mandatory) Key used to open the encrypted database. If this parameter is not specified, the database generates and saves the key and uses the generated key to open the database file.
133      iterationCount: 25000, // (Optional) Number of iterations. The value must be greater than or equal to 0. If this parameter is not specified or is set to 0, the default value 10000 and the default encryption algorithm are used.
134      encryptionAlgo: relationalStore.EncryptionAlgo.AES_256_CBC, // (Optional) Encryption/Decryption algorithm. If this parameter is not specified, the default algorithm AES_256_GCM is used.
135      hmacAlgo: relationalStore.HmacAlgo.SHA256, // (Optional) HMAC algorithm. If this parameter is not specified, the default value SHA256 is used.
136      kdfAlgo: relationalStore.KdfAlgo.KDF_SHA512, // (Optional) KDF algorithm. If this parameter is not specified, the default value (same as the HMAC algorithm) is used.
137      cryptoPageSize: 2048 // (Optional) Page size used for encryption/decryption. The value must be an integer within the range of 1024 to 65536 and a power of 2. The default value is 1024.
138    }
139
140    const STORE_CONFIG: relationalStore.StoreConfig = {
141      name: "encrypted.db",
142      securityLevel: relationalStore.SecurityLevel.S3,
143      encrypt: true,
144      cryptoParam: CRYPTO_PARAM
145    }
146    try {
147      let store = await relationalStore.getRdbStore(context, STORE_CONFIG);
148      if (store == null) {
149        console.error('Failed to get RdbStore.');
150      } else {
151        console.info('Succeeded in getting RdbStore.');
152      }
153      // Clear the key.
154      CRYPTO_PARAM.encryptionKey.fill(0);
155    } catch (e) {
156      const err = e as BusinessError;
157      console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
158    }
159  }
160}
161```
162
163If you do not care about the algorithm and other parameters used for encryption, leave **cryptoParam** unspecified. In this case, the default encryption configuration is used. If you want to customize the encryption configuration or open an encrypted database that is not configured by default, set **cryptoParam**.
164