Skip to content

Commit 74a978b

Browse files
committed
Add SetReKey for SQLCipher
1 parent 0b23275 commit 74a978b

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

src/SQLite.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,32 @@ void SetKey (byte[] key)
390390
ExecuteScalar<string> ("pragma key = \"x'" + s + "'\"");
391391
}
392392

393+
/// <summary>
394+
/// Change the encryption key for a SQLCipher database with "pragma rekey = ...".
395+
/// </summary>
396+
/// <param name="key">Encryption key plain text that is converted to the real encryption key using PBKDF2 key derivation</param>
397+
public void SetReKey (string key)
398+
{
399+
if (key == null)
400+
throw new ArgumentNullException(nameof(key));
401+
var q = Quote(key);
402+
ExecuteScalar<string>("pragma rekey = " + q);
403+
}
404+
405+
/// <summary>
406+
/// Change the encryption key for a SQLCipher database.
407+
/// </summary>
408+
/// <param name="key">256-bit (32 byte) or 384-bit (48 bytes) encryption key data</param>
409+
public void SetReKey (byte[] key)
410+
{
411+
if (key == null)
412+
throw new ArgumentNullException(nameof(key));
413+
if (key.Length != 32 && key.Length != 48)
414+
throw new ArgumentException ("Key must be 32 bytes (256-bit) or 48 bytes (384-bit)", nameof (key));
415+
var s = String.Join("", key.Select(x => x.ToString("X2")));
416+
ExecuteScalar<string>("pragma rekey = \"x'" + s + "'\"");
417+
}
418+
393419
/// <summary>
394420
/// Enable or disable extension loading.
395421
/// </summary>

tests/SQLite.Tests/SQLCipherTest.cs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,75 @@ public void CheckJournalModeForNonKeyed ()
148148
Assert.AreEqual ("wal", db.ExecuteScalar<string> ("PRAGMA journal_mode;"));
149149
}
150150
}
151+
152+
[Test]
153+
public void ResetStringKey ()
154+
{
155+
string path;
156+
157+
var key = "SecretPassword";
158+
var reKey = "SecretKey";
159+
160+
using (var db = new TestDb (key: key)) {
161+
db.SetReKey (reKey);
162+
path = db.DatabasePath;
163+
164+
db.CreateTable<TestTable> ();
165+
db.Insert (new TestTable { Value = "Hello" });
166+
}
167+
168+
using (var db = new TestDb (path, key: reKey)) {
169+
path = db.DatabasePath;
170+
171+
var r = db.Table<TestTable> ().First ();
172+
173+
Assert.AreEqual ("Hello", r.Value);
174+
}
175+
}
176+
177+
[Test]
178+
public void ResetByteKey ()
179+
{
180+
string path;
181+
182+
var rand = new Random ();
183+
var key = new byte[32];
184+
rand.NextBytes (key);
185+
var reKey = new byte[32];
186+
rand.NextBytes (reKey);
187+
188+
using (var db = new TestDb (key: key)) {
189+
db.SetReKey (reKey);
190+
path = db.DatabasePath;
191+
192+
db.CreateTable<TestTable> ();
193+
db.Insert (new TestTable { Value = "Hello" });
194+
}
195+
196+
using (var db = new TestDb (path, key: reKey)) {
197+
path = db.DatabasePath;
198+
199+
var r = db.Table<TestTable> ().First ();
200+
201+
Assert.AreEqual ("Hello", r.Value);
202+
}
203+
}
204+
205+
[Test]
206+
public void ResetBadKey ()
207+
{
208+
var key = new byte[] { 42 };
209+
210+
try
211+
{
212+
using (var db = new TestDb ()) {
213+
db.SetReKey (key);
214+
}
215+
216+
Assert.Fail ("Should have thrown");
217+
}
218+
catch (ArgumentException) {
219+
}
220+
}
151221
}
152222
}

0 commit comments

Comments
 (0)