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