• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 数据库加密 (ArkTS)
2<!--Kit: ArkData-->
3<!--Subsystem: DistributedDataManager-->
4<!--Owner: @baijidong-->
5<!--Designer: @widecode; @htt1997; @dboy190-->
6<!--Tester: @yippo; @logic42-->
7<!--Adviser: @ge-yafang-->
8
9## 场景介绍
10
11为了增强数据库的安全性,数据库提供了一个安全适用的数据库加密能力,从而对数据库存储的内容实施有效保护。通过数据库加密等安全方法实现了数据库数据存储的保密性和完整性要求,使得数据库以密文方式存储并在密态方式下工作,确保了数据安全。
12
13加密后的数据库只能通过接口进行访问,无法通过其它方式打开数据库文件。数据库的加密属性在创建数据库时确认,无法变更。
14
15键值型数据库和关系型数据库均支持数据库加密操作,其中关系型数据库支持自定义加密/解密的密钥和其他参数。
16
17
18## 键值型数据库加密
19
20键值型数据库,通过options中encrypt参数来设置是否加密,默认为false,表示不加密。encrypt参数为true时表示加密。
21
22具体接口及功能,可见[分布式键值数据库](../reference/apis-arkdata/js-apis-distributedKVStore.md)。
23
24```ts
25import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
26import { hilog } from '@kit.PerformanceAnalysisKit';
27import { distributedKVStore } from '@kit.ArkData';
28import { BusinessError } from '@kit.BasicServicesKit';
29
30export default class EntryAbility extends UIAbility {
31  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
32    this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
33    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
34    let kvManager: distributedKVStore.KVManager | undefined = undefined;
35    let kvStore: distributedKVStore.SingleKVStore | undefined = undefined;
36    let context = this.context;
37    const kvManagerConfig: distributedKVStore.KVManagerConfig = {
38      context: context,
39      bundleName: 'com.example.datamanagertest',
40    }
41    try {
42      kvManager = distributedKVStore.createKVManager(kvManagerConfig);
43      console.info('Succeeded in creating KVManager.');
44    } catch (e) {
45      let error = e as BusinessError;
46      console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`);
47    }
48    if (kvManager !== undefined) {
49      try {
50        const options: distributedKVStore.Options = {
51          createIfMissing: true,
52          // 设置数据库加密
53          encrypt: true,
54          backup: false,
55          autoSync: false,
56          kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
57          securityLevel: distributedKVStore.SecurityLevel.S3
58        };
59        kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', options, (err, store: distributedKVStore.SingleKVStore) => {
60          if (err) {
61            console.error(`Fail to get KVStore. Code:${err.code},message:${err.message}`);
62            return;
63          }
64          console.info('Succeeded in getting KVStore.');
65          kvStore = store;
66          if (kvStore !== undefined) {
67            //进行后续操作
68            //...
69          }
70        });
71      } catch (e) {
72        let error = e as BusinessError;
73        console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`);
74      }
75    }
76  }
77}
78```
79
80## 关系型数据库加密
81
82关系型数据库,通过[StoreConfig](../reference/apis-arkdata/arkts-apis-data-relationalStore-i.md#storeconfig)中encrypt属性来设置是否加密。encrypt参数为true时表示加密;为false时表示不加密;默认值为false。
83
84当encrypt为true时,支持开发者通过ArkTs API中的可选属性cryptoParam设置自定义的加密/解密密钥和算法等参数。
85
86针对cryptoParam的配置与否,有如下两种场景:
87
88场景1:不配置cryptoParam属性,此时会使用默认的加密配置进行数据库的加密/解密。
89
90
91```ts
92import { UIAbility } from '@kit.AbilityKit';
93import { relationalStore } from '@kit.ArkData';
94import { BusinessError } from '@kit.BasicServicesKit';
95
96export default class EntryAbility extends UIAbility {
97  async onCreate(): Promise<void> {
98    let store: relationalStore.RdbStore | undefined = undefined;
99    let context = this.context;
100
101    try {
102      const STORE_CONFIG: relationalStore.StoreConfig = {
103        name: 'RdbTest.db',
104        securityLevel: relationalStore.SecurityLevel.S3,
105        encrypt: true
106      };
107      store = await relationalStore.getRdbStore(context, STORE_CONFIG);
108      console.info('Succeeded in getting RdbStore.');
109    } catch (e) {
110      const err = e as BusinessError;
111      console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
112    }
113  }
114}
115```
116
117场景2:配置cryptoParam属性,此时会使用开发者自定义的密钥和算法参数进行数据库的加密/解密。
118
119```ts
120import { UIAbility } from '@kit.AbilityKit';
121import { relationalStore } from '@kit.ArkData';
122import { BusinessError } from '@kit.BasicServicesKit';
123
124export default class EntryAbility extends UIAbility {
125  async onCreate(): Promise<void> {
126    let store: relationalStore.RdbStore | undefined = undefined;
127    let context = this.context;
128    // 初始化需要使用的密钥
129    let key = new Uint8Array(32);
130    for (let i = 0; i < 32; i++) {
131      key[i] = i;
132    }
133
134    // 初始化加密算法
135    const CRYPTO_PARAM: relationalStore.CryptoParam = {
136      encryptionKey: key, // 必选参数,使用指定的密钥打开加密数据库。为空则由数据库负责生成并保存密钥,并使用生成的密钥打开数据库文件。
137      iterationCount: 25000, // 可选参数,迭代次数。迭代次数必须大于零。不指定或等于零则使用默认值10000和默认加密算法。
138      encryptionAlgo: relationalStore.EncryptionAlgo.AES_256_CBC, // 可选参数,加密/解密算法。如不指定,默认算法为AES_256_GCM。
139      hmacAlgo: relationalStore.HmacAlgo.SHA256, // 可选参数,HMAC算法。如不指定,默认值为SHA256。
140      kdfAlgo: relationalStore.KdfAlgo.KDF_SHA512, // 可选参数,KDF算法。如不指定,默认值和HMAC算法相等。
141      cryptoPageSize: 2048 // 可选参数,加密/解密时使用的页大小。必须为1024到65536范围内的整数并且为2的幂。如不指定,默认值为1024。
142    }
143
144    const STORE_CONFIG: relationalStore.StoreConfig = {
145      name: "encrypted.db",
146      securityLevel: relationalStore.SecurityLevel.S3,
147      encrypt: true,
148      cryptoParam: CRYPTO_PARAM
149    }
150    try {
151      store = await relationalStore.getRdbStore(context, STORE_CONFIG);
152      if (store == null) {
153        console.error('Failed to get RdbStore.');
154      } else {
155        console.info('Succeeded in getting RdbStore.');
156      }
157      // 调用完后需要将密钥清零
158      CRYPTO_PARAM.encryptionKey.fill(0);
159    } catch (e) {
160      const err = e as BusinessError;
161      console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
162    }
163  }
164}
165```
166
167如果开发者不关心加密使用的算法及参数,则无需配置cryptoParam属性,使用默认加密配置即可。当开发者需要自定义加密配置,或需要打开非默认配置的加密数据库时,则需要配置cryptoParam属性。
168