1# Database Encryption 2 3 4## When to Use 5 6OpenHarmony 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. 7 8The 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. 9 10Both KV stores and RDB stores support database encryption. For RDB stores, you can custom the encryption/decryption keys and other parameters. 11 12 13## Encrypting a KV Store 14 15When 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. 16 17For details about the APIs, see [Distributed KV Store](../reference/apis-arkdata/js-apis-distributedKVStore.md). 18 19```ts 20import { distributedKVStore } from '@kit.ArkData'; 21import { BusinessError } from '@kit.BasicServicesKit'; 22 23let kvManager: distributedKVStore.KVManager | undefined = undefined; 24let kvStore: distributedKVStore.SingleKVStore | undefined = undefined; 25let context = getContext(this); 26const kvManagerConfig: distributedKVStore.KVManagerConfig = { 27 context: context, 28 bundleName: 'com.example.datamanagertest', 29} 30try { 31 kvManager = distributedKVStore.createKVManager(kvManagerConfig); 32 console.info('Succeeded in creating KVManager.'); 33} catch (e) { 34 let error = e as BusinessError; 35 console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`); 36} 37if (kvManager !== undefined) { 38 kvManager = kvManager as distributedKVStore.KVManager; 39 try { 40 const options: distributedKVStore.Options = { 41 createIfMissing: true, 42 // Whether to encrypt the KV store. 43 encrypt: true, 44 backup: false, 45 autoSync: false, 46 kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, 47 securityLevel: distributedKVStore.SecurityLevel.S3 48 }; 49 kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', options, (err, store: distributedKVStore.SingleKVStore) => { 50 if (err) { 51 console.error(`Fail to get KVStore. Code:${err.code},message:${err.message}`); 52 return; 53 } 54 console.info('Succeeded in getting KVStore.'); 55 kvStore = store; 56 }); 57 } catch (e) { 58 let error = e as BusinessError; 59 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 60 } 61} 62if (kvStore !== undefined) { 63 kvStore = kvStore as distributedKVStore.SingleKVStore; 64 // Perform subsequent operations. 65 //... 66} 67``` 68 69 70## Encrypting an RDB Store 71 72The **encrypt** property in [StoreConfig](../reference/apis-arkdata/js-apis-data-relationalStore.md#storeconfig) specifies whether to encrypt the RDB store. The value **true** means to encrypt the RDB store, and **false** means the opposite. 73 74If **encrypt** is **true**, you can set parameters such as the key and algorithm used for encryption/decryption in **cryptoParam**. 75 76The **cryptoParam** parameter is optional. 77 78If **cryptoParam** is not set, the default configuration is used for database encryption and decryption. 79 80 81```ts 82import { relationalStore } from '@kit.ArkData'; 83 84let store: relationalStore.RdbStore; 85let context = getContext(this); 86const STORE_CONFIG: relationalStore.StoreConfig = { 87 name: 'RdbTest.db', 88 securityLevel: relationalStore.SecurityLevel.S3, 89 encrypt: true 90}; 91relationalStore.getRdbStore(context, STORE_CONFIG, (err, rdbStore) => { 92 store = rdbStore; 93 if (err) { 94 console.error(`Failed to get RdbStore. Code:${err.code},message:${err.message}`); 95 return; 96 } 97 console.info('Succeeded in getting RdbStore.'); 98}) 99``` 100 101If **cryptoParam** is set, the specified key and algorithm are used for database encryption and decryption. 102 103```ts 104import { relationalStore } from '@kit.ArkData'; 105 106let context = getContext(this); 107 108// Initialize the key to be used. 109let key = new Uint8Array(32); 110for (let i = 0; i < 32; i++) { 111 key[i] = i; 112} 113 114// Initialize the encryption algorithm. 115const CRYPTO_PARAM : relationalStore.CryptoParam = { 116 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. 117 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. 118 encryptionAlgo: relationalStore.EncryptionAlgo.AES_256_CBC, // (Optional) Encryption/Decryption algorithm. If this parameter is not specified, the default algorithm AES_256_GCM is used. 119 hmacAlgo: relationalStore.HmacAlgo.SHA256, // (Optional) HMAC algorithm. If this parameter is not specified, the default value SHA256 is used. 120 kdfAlgo: relationalStore.KdfAlgo.KDF_SHA512, // (Optional) KDF algorithm. If this parameter is not specified, the default value (same as the HMAC algorithm) is used. 121 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. 122} 123 124const STORE_CONFIG : relationalStore.StoreConfig = { 125 name: "encrypted.db", 126 securityLevel: relationalStore.SecurityLevel.S3, 127 encrypt: true, 128 cryptoParam: CRYPTO_PARAM 129} 130 131async function run() { 132 let store = await relationalStore.getRdbStore(context, STORE_CONFIG); 133 if (store == null) { 134 console.error('Failed to get RdbStore.'); 135 } else { 136 console.info('Succeeded in getting RdbStore.'); 137 } 138 // Clear the key. 139 CRYPTO_PARAM.encryptionKey.fill(0); 140} 141 142run(); 143``` 144 145If 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**. 146 147