İçeriğe geç
NarDBv0.2.0-dev

Şifreleme

Diskte şifreleme, anahtarın nerede durduğu, parola değişimi ve anahtar yenileme.

Şifreli bir veritabanında her sayfa diske yazılmadan önce şifrelenir: catalog.db, indexes.db, partition dosyaları ve yazma günlüğü (wal.log). Dosyaları kopyalayan biri satırları, kullanıcı adlarını, parola özetlerini ve şema adlarını okuyamaz.

NarDB Shell yeni veritabanlarını varsayılan olarak şifreli oluşturur.

Anahtar nerede durur#

İki katman vardır:

AnahtarNe yaparNerede
Veri anahtarıSayfaları şifreler; her veritabanına özel, rastgele 32 baytnardb.toml'da, yalnızca sarılı (ana anahtarla şifrelenmiş) olarak
Ana anahtarVeri anahtarını sararSistem anahtar deposunda ya da bir paroladan türetilir

Ana anahtar hiçbir zaman veritabanının yanında durmaz.

KaynakNe zaman
keychainTek makine, masaüstü. Açarken bir şey sorulmaz. macOS Keychain, Windows Credential Manager, Linux Secret Service.
passphraseVeritabanı başka makineye taşınacaksa ya da anahtar hiçbir yerde saklanmasın isteniyorsa. Her açılışta parola sorulur. En az 12 karakter; ana anahtar Argon2id ile türetilir.

Oluşturmak#

Shell'de File → New ▸ Database... dialogu şifreleme seçeneğini sorar. Komut satırında:

Terminal
>> create_local_database -f ./veri/magaza.ndbc                  # anahtar deposunda (varsayılan)
>> create_local_database -f ./veri/magaza.ndbc -e passphrase    # parola sorar
>> create_local_database -f ./veri/deneme.ndbc -e none          # şifresiz

Go API'sinde:

Go
import "nardb/keychain"

db, err := nardb.Open("./veri/magaza.ndbc", nardb.Options{
    Encryption: nardb.EncryptKeychain,
    Keychain:   keychain.System{},
})

Parolayla şifreli bir veritabanı parolasız açılmaya çalışılırsa nardb.ErrPassphraseRequired, yanlış parolayla nardb.ErrWrongPassphrase döner. Shell ilk durumda parolayı sorar.

Var olan bir veritabanını şifrelemek#

Terminal
>> encrypt_database                 # anahtar deposuna
>> encrypt_database -e passphrase   # parolayla

Şifresiz bir veritabanında bu komut bütün veriyi yeni, şifreli bir kapsayıcıya kopyalar ve eskisinin yerine koyar; eski dosyalar silinir. Go'da nardb.Reencrypt(path, from, to).

Parolayı ya da anahtar kaynağını değiştirmek#

Zaten şifreli bir veritabanında encrypt_database yalnızca ana anahtarı değiştirir: parola değişimi, anahtar deposuna geçiş ya da tersi. Veri anahtarı yeniden sarılır, sayfalar yeniden şifrelenmez; işlem anında biter. Go'da db.ChangeKey(opts).

Anahtar deposundaki her anahtar nesli ayrı bir kayıttır. Önce yeni kayıt yazılır, sonra nardb.toml, en son eski kayıt silinir. Arada bir kesinti olursa nardb.toml hâlâ geçerli olan eski kaydı gösterir; veritabanı kilitli kalmaz.

Veri anahtarını yenilemek#

Terminal
>> rotate_key

Bütün sayfalar yeni bir veri anahtarıyla yeniden yazılır, anahtar kaynağı aynı kalır. Bir anahtarın sızmış olabileceğinden şüpheleniyorsanız bunu kullanın. İşlem bir kopya üzerinde yapılır ve yarıda kesilirse bir sonraki açılışta tamamlanır.

Neyi korur, neyi korumaz#

Korur:

  • Dosyaların, diskin ya da yedeklerin kopyalanması.
  • Bir sayfanın değiştirilmesi ya da başka bir yere taşınması: her sayfa bulunduğu dosyaya ve konuma bağlıdır, okuma hata verir.
  • Sarılı anahtarın başka bir veritabanına kopyalanması: açılmaz.

Korumaz:

  • Veritabanı açıkken o makinede çalışan bir saldırgan: açık sayfalar bellektedir.
  • Bir sayfanın kendi eski şifreli haliyle değiştirilmesi (geri alma); bunu yakalamak için sayfa sürümlerini tutan bir yapı gerekir.
  • Dosya başlıkları (sayfa sayısı, sürüm) ve dosya sayısı açıktır; içerik değildir.

Teknik ayrıntı#

  • Algoritma XChaCha20-Poly1305 (golang.org/x/crypto). Her yazmada rastgele 24 baytlık bir nonce üretilir; doğrulama etiketi 16 bayttır.
  • 4 KiB'lık bir sayfanın 40 baytı nonce ve etikete gider; tablolar 4056 baytlık sayfa görür.
  • Ek doğrulanan veri: kapsayıcı kimliği, dosya yolu, sayfa numarası.
  • Önbellekte sayfaların açık hali tutulur; şifre bir sayfa için bir kez çözülür.