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