# एन्क्रिप्टेड SQLite डेटाबेस का उपयोग कैसे करें

> कुंजी के साथ खोलना, सिफर चुनना, कुंजी बदलना/हटाना और गलत कुंजी का पता लगाना।

Source: https://crossfly.dev/hi/docs/cookbook/data/banco-criptografado — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# एन्क्रिप्टेड SQLite डेटाबेस का उपयोग कैसे करें

**उद्देश्य.** संवेदनशील डेटा को डिस्क पर एक सिफर किए गए डेटाबेस (SQLite3MC के माध्यम से) के साथ सुरक्षित करना। एन्क्रिप्शन **opt-in** है: कुंजी के बिना डेटाबेस एक सामान्य SQLite है, बिना किसी सिफर लागत के। कुंजी के साथ, CrossFly सिफर लागू करता है और कुंजी को **खोलने पर** मान्य करता है (जल्दी विफल होता है, पहली query पर नहीं)।

## उपयोग की गई APIs
- `SqliteDb.open(String filename, byte[] key)` — **डिफ़ॉल्ट सिफर** `Sqlite.Cipher.CHACHA20` (ChaCha20-Poly1305) के साथ सिफर किया हुआ खोलता/बनाता है।
- `SqliteDb.open(String filename, byte[] key, Sqlite.Cipher cipher)` — स्पष्ट सिफर के साथ खोलता है। विकल्प: `CHACHA20`, `SQLCIPHER` (AES-256-CBC + HMAC), `AES128CBC`, `AES256CBC`, `RC4`, `ASCON128`।
- `SqliteDb.rekey(byte[] newKey)` — `sqlite3_rekey` के माध्यम से कुंजी बदलता है। `null` या **खाली** array (`new byte[0]`) पास करना एन्क्रिप्शन को **हटा** देता है ("rekey to no key")।
- `SqliteException.code` — त्रुटि का संख्यात्मक कोड। `Sqlite` के स्थिरांकों से तुलना करें। **गलत कुंजी / फ़ाइल डेटाबेस नहीं है** ⇒ `code == Sqlite.NOTADB` (**26**)। अन्य उपयोगी: `Sqlite.BUSY` (5), `Sqlite.CONSTRAINT` (19)।

> **गलत कुंजी कैसे दिखती है।** कुंजी के साथ `open` में, CrossFly सिफर का चयन करता है, कुंजी लागू करता है और एक बलपूर्वक पठन (`SELECT count(*) FROM sqlite_master`) करता है ताकि गलत कुंजी के साथ **तुरंत** विफल हो सके, कनेक्शन बंद करते हुए। आप `SqliteException` को `code == Sqlite.NOTADB` के साथ पकड़ते हैं।

> **पुनः खोलते समय सिफर का ध्यान रखें।** किसी मौजूदा डेटाबेस को पुनः खोलने के लिए, उसी **सिफर** का उपयोग करें जिसके साथ इसे बनाया गया था। `CHACHA20` (डिफ़ॉल्ट) केवल `CHACHA20` डेटाबेस को डिक्रिप्ट करता है; एक `SQLCIPHER` डेटाबेस को `open(file, key, Sqlite.Cipher.SQLCIPHER)` की आवश्यकता होती है।

## पूर्ण उदाहरण (कॉपी करें, पेस्ट करें और चलाएँ)

```java
package com.exemplo;

import java.nio.charset.StandardCharsets;

import dev.crossfly.ui.*;                     // Window
import dev.crossfly.ui.layout.*;             // VerticalLayout
import dev.crossfly.sqlite.*;                // SqliteDb, Sqlite, SqliteException

/** चलाने योग्य मुख्य स्क्रीन। launcher (classname) की ओर संकेत करें और चलाएँ: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      byte[] key = "minha-senha-forte".getBytes(StandardCharsets.UTF_8);

      // एन्क्रिप्टेड खोलें/बनाएँ (डिफ़ॉल्ट cipher CHACHA20)
      try (SqliteDb db = SqliteDb.open("secure.db", key))
      {
         db.exec("CREATE TABLE IF NOT EXISTS secret(id INTEGER PRIMARY KEY, v TEXT)");
         db.execute("INSERT INTO secret(v) VALUES(?)", "dado sensível");

         // कुंजी बदलें
         byte[] novaKey = "senha-ainda-mais-forte".getBytes(StandardCharsets.UTF_8);
         db.rekey(novaKey);
         // db.rekey(new byte[0]);  // <- एन्क्रिप्शन हटा देगा
      }

      // स्पष्ट cipher (SQLCipher के साथ संगत)
      try (SqliteDb db = SqliteDb.open("sqlcipher.db", key, Sqlite.Cipher.SQLCIPHER))
      {
         db.exec("SELECT count(*) FROM sqlite_master");
      }

      // गलत कुंजी का पता लगाएँ
      try (SqliteDb db = SqliteDb.open("secure.db", "chave-errada".getBytes(StandardCharsets.UTF_8)))
      {
         // यहाँ नहीं पहुँचता: open में सत्यापन पहले ही विफल हो गया
      }
      catch (SqliteException e)
      {
         if (e.code == Sqlite.NOTADB)          // 26 = गलत कुंजी / डेटाबेस नहीं है
            System.out.println("Chave incorreta");
         else
            throw e;
      }
   }
}
```

> नीचे दिया गया अंश **केवल मुख्य भाग** दिखाता है। इसे चलाने के लिए, इसे ऊपर दिए गए `MainWindow` ढाँचे में रखें।

## न्यूनतम अंश
```java
// स्रोत में सत्यापित: open(file,key), open(file,key,cipher), rekey, SqliteException.code == Sqlite.NOTADB
import dev.crossfly.sqlite.*;
import java.nio.charset.StandardCharsets;

byte[] key = "minha-senha-forte".getBytes(StandardCharsets.UTF_8);

// एन्क्रिप्टेड खोलें/बनाएँ (डिफ़ॉल्ट cipher CHACHA20)
try (SqliteDb db = SqliteDb.open("secure.db", key))
{
   db.exec("CREATE TABLE IF NOT EXISTS secret(id INTEGER PRIMARY KEY, v TEXT)");
   db.execute("INSERT INTO secret(v) VALUES(?)", "dado sensível");

   // कुंजी बदलें
   byte[] novaKey = "senha-ainda-mais-forte".getBytes(StandardCharsets.UTF_8);
   db.rekey(novaKey);
   // db.rekey(new byte[0]);  // <- एन्क्रिप्शन हटा देगा
}

// स्पष्ट cipher (SQLCipher के साथ संगत)
try (SqliteDb db = SqliteDb.open("sqlcipher.db", key, Sqlite.Cipher.SQLCIPHER))
{
   db.exec("SELECT count(*) FROM sqlite_master");
}

// गलत कुंजी का पता लगाएँ
try (SqliteDb db = SqliteDb.open("secure.db", "chave-errada".getBytes(StandardCharsets.UTF_8)))
{
   // यहाँ नहीं पहुँचता: open में सत्यापन पहले ही विफल हो गया
}
catch (SqliteException e)
{
   if (e.code == Sqlite.NOTADB)          // 26 = गलत कुंजी / डेटाबेस नहीं है
      System.out.println("Chave incorreta");
   else
      throw e;
}
```

## और गहराई से जानें
- [सुरक्षा की सर्वोत्तम प्रथाएँ](/docs/best-practices/seguranca) · [SQLite स्टोरेज गाइड](/docs/data-and-services/storage-sqlite)
- सहयोगी रेसिपी: [डेटाबेस खोलें/बनाएँ](/docs/cookbook/data/abrir-banco) · [पैरामीट्रिकृत CRUD](/docs/cookbook/data/crud)
