---
title: "Can IndexedDB be encrypted for sensitive data? How would you do that?"  
description: "Can IndexedDB be encrypted for sensitive data? How would you do that?"  
author: "ICSM Computer"  
published: 2025-07-13  
updated: 2025-07-13  
canonical: https://www.mindstick.com/interview/34335/can-indexeddb-be-encrypted-for-sensitive-data-how-would-you-do-that  
category: "IndexedDB"  
tags: ["database", "indexeddb"]  
reading_time: 5 minutes  

---

# Can IndexedDB be encrypted for sensitive data? How would you do that?

Yes, [**IndexedDB**](https://www.mindstick.com/interview/34289/what-is-indexeddb) **can store encrypted data**, but it does **not offer encryption by default**. To protect sensitive data—such as personal information, tokens, or health records—you must **manually encrypt** the data **before storing it** and **decrypt** it when retrieving.

### Why [Encrypt IndexedDB](https://www.mindstick.com/interview/34312/what-are-the-security-and-privacy-considerations-when-using-indexeddb)?

- **IndexedDB is accessible via browser developer tools.**
- **Stored data is not encrypted at rest**—it’s stored in plain text.
- **If an attacker gains access to the device or browser profile**, they could extract sensitive data.
- So, **client-side encryption is essential** for sensitive or regulated applications (e.g., HIPAA, GDPR).

## How to Encrypt IndexedDB Data

Here’s a step-by-step guide using the **Web Crypto API**, which is built into all modern browsers.

### 1. Generate or Import a Crypto Key

Use a symmetric key (e.g., AES-GCM) for encrypting and decrypting.

```javascript
async function generateKey() {
  return crypto.subtle.generateKey(
    { name: "AES-GCM", length: 256 },
    true,
    ["encrypt", "decrypt"]
  );
}
```

Or import an existing key:

```javascript
async function importKey(rawKey) {
  return crypto.subtle.importKey(
    "raw",
    rawKey,
    "AES-GCM",
    true,
    ["encrypt", "decrypt"]
  );
}
```

### 2. Encrypt Data Before Storing

```javascript
async function encryptData(key, data) {
  const enc = new TextEncoder();
  const iv = crypto.getRandomValues(new Uint8Array(12)); // 96-bit IV
  const encrypted = await crypto.subtle.encrypt(
    { name: "AES-GCM", iv },
    key,
    enc.encode(JSON.stringify(data))
  );

  return {
    iv: Array.from(iv),
    data: Array.from(new Uint8Array(encrypted))
  };
}
```

Then store this encrypted payload in IndexedDB.

### 3. Decrypt When Reading

```javascript
async function decryptData(key, encrypted) {
  const iv = new Uint8Array(encrypted.iv);
  const data = new Uint8Array(encrypted.data);
  const decrypted = await crypto.subtle.decrypt(
    { name: "AES-GCM", iv },
    key,
    data
  );

  const dec = new TextDecoder();
  return JSON.parse(dec.decode(decrypted));
}
```

### 4. Save and Load in IndexedDB

Here’s a basic example of saving an encrypted object:

```javascript
const key = await generateKey();
const encrypted = await encryptData(key, { secret: "Sensitive info" });
await db.store.put({ id: "s1", value: encrypted });
```

And reading/decrypting it later:

```javascript
const encrypted = await db.store.get("s1");
const data = await decryptData(key, encrypted.value);
console.log(data.secret);
```

## When to Encrypt

Encrypt in IndexedDB when you:

- Store passwords, tokens, health records, personal identifiers (PII).
- Operate in regulated industries (finance, healthcare).
- Need to prevent casual snooping via devtools.

### Summary

| Step | Action |
| --- | --- |
| No built-in encryption | Must encrypt manually using Web Crypto API |
| Encrypt before storing | AES-GCM with IV |
| Decrypt after reading | Convert to original object |
| Key storage | NEVER store keys in IndexedDB |
| Use case | PII, tokens, compliance data |

## Answers

### Answer by ICSM Computer

Yes, [**IndexedDB**](https://www.mindstick.com/interview/34289/what-is-indexeddb) **can store encrypted data**, but it does **not offer encryption by default**. To protect sensitive data—such as personal information, tokens, or health records—you must **manually encrypt** the data **before storing it** and **decrypt** it when retrieving.

### Why [Encrypt IndexedDB](https://www.mindstick.com/interview/34312/what-are-the-security-and-privacy-considerations-when-using-indexeddb)?

- **IndexedDB is accessible via browser developer tools.**
- **Stored data is not encrypted at rest**—it’s stored in plain text.
- **If an attacker gains access to the device or browser profile**, they could extract sensitive data.
- So, **client-side encryption is essential** for sensitive or regulated applications (e.g., HIPAA, GDPR).

## How to Encrypt IndexedDB Data

Here’s a step-by-step guide using the **Web Crypto API**, which is built into all modern browsers.

### 1. Generate or Import a Crypto Key

Use a symmetric key (e.g., AES-GCM) for encrypting and decrypting.

```javascript
async function generateKey() {
  return crypto.subtle.generateKey(
    { name: "AES-GCM", length: 256 },
    true,
    ["encrypt", "decrypt"]
  );
}
```

Or import an existing key:

```javascript
async function importKey(rawKey) {
  return crypto.subtle.importKey(
    "raw",
    rawKey,
    "AES-GCM",
    true,
    ["encrypt", "decrypt"]
  );
}
```

### 2. Encrypt Data Before Storing

```javascript
async function encryptData(key, data) {
  const enc = new TextEncoder();
  const iv = crypto.getRandomValues(new Uint8Array(12)); // 96-bit IV
  const encrypted = await crypto.subtle.encrypt(
    { name: "AES-GCM", iv },
    key,
    enc.encode(JSON.stringify(data))
  );

  return {
    iv: Array.from(iv),
    data: Array.from(new Uint8Array(encrypted))
  };
}
```

Then store this encrypted payload in IndexedDB.

### 3. Decrypt When Reading

```javascript
async function decryptData(key, encrypted) {
  const iv = new Uint8Array(encrypted.iv);
  const data = new Uint8Array(encrypted.data);
  const decrypted = await crypto.subtle.decrypt(
    { name: "AES-GCM", iv },
    key,
    data
  );

  const dec = new TextDecoder();
  return JSON.parse(dec.decode(decrypted));
}
```

### 4. Save and Load in IndexedDB

Here’s a basic example of saving an encrypted object:

```javascript
const key = await generateKey();
const encrypted = await encryptData(key, { secret: "Sensitive info" });
await db.store.put({ id: "s1", value: encrypted });
```

And reading/decrypting it later:

```javascript
const encrypted = await db.store.get("s1");
const data = await decryptData(key, encrypted.value);
console.log(data.secret);
```

## When to Encrypt

Encrypt in IndexedDB when you:

- Store passwords, tokens, health records, personal identifiers (PII).
- Operate in regulated industries (finance, healthcare).
- Need to prevent casual snooping via devtools.

### Summary

| Step | Action |
| --- | --- |
| No built-in encryption | Must encrypt manually using Web Crypto API |
| Encrypt before storing | AES-GCM with IV |
| Decrypt after reading | Convert to original object |
| Key storage | NEVER store keys in IndexedDB |
| Use case | PII, tokens, compliance data |


---

Original Source: https://www.mindstick.com/interview/34335/can-indexeddb-be-encrypted-for-sensitive-data-how-would-you-do-that

Copyright © MindStick Software Pvt. Ltd. This Markdown version is provided for developers, AI systems, and offline reading.
