Skip to content

Commit e79dd0e

Browse files
authored
Merge pull request #1089 from shiena/sqlcipher/setrekey
Add SetReKey for SQLCipher
2 parents df96ed1 + bbdb422 commit e79dd0e

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

src/SQLite.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ static string Quote (string unsafeString)
462462
/// if your database is encrypted.
463463
/// This only has an effect if you are using the SQLCipher nuget package.
464464
/// </summary>
465-
/// <param name="key">Ecryption key plain text that is converted to the real encryption key using PBKDF2 key derivation</param>
465+
/// <param name="key">Encryption key plain text that is converted to the real encryption key using PBKDF2 key derivation</param>
466466
void SetKey (string key)
467467
{
468468
if (key == null)
@@ -477,7 +477,7 @@ void SetKey (string key)
477477
/// if your database is encrypted.
478478
/// This only has an effect if you are using the SQLCipher nuget package.
479479
/// </summary>
480-
/// <param name="key">256-bit (32 byte) ecryption key data</param>
480+
/// <param name="key">256-bit (32 byte) encryption key data</param>
481481
void SetKey (byte[] key)
482482
{
483483
if (key == null)
@@ -488,6 +488,32 @@ void SetKey (byte[] key)
488488
ExecuteScalar<string> ("pragma key = \"x'" + s + "'\"");
489489
}
490490

491+
/// <summary>
492+
/// Change the encryption key for a SQLCipher database with "pragma rekey = ...".
493+
/// </summary>
494+
/// <param name="key">Encryption key plain text that is converted to the real encryption key using PBKDF2 key derivation</param>
495+
public void SetReKey (string key)
496+
{
497+
if (key == null)
498+
throw new ArgumentNullException(nameof(key));
499+
var q = Quote(key);
500+
ExecuteScalar<string>("pragma rekey = " + q);
501+
}
502+
503+
/// <summary>
504+
/// Change the encryption key for a SQLCipher database.
505+
/// </summary>
506+
/// <param name="key">256-bit (32 byte) or 384-bit (48 bytes) encryption key data</param>
507+
public void SetReKey (byte[] key)
508+
{
509+
if (key == null)
510+
throw new ArgumentNullException(nameof(key));
511+
if (key.Length != 32 && key.Length != 48)
512+
throw new ArgumentException ("Key must be 32 bytes (256-bit) or 48 bytes (384-bit)", nameof (key));
513+
var s = String.Join("", key.Select(x => x.ToString("X2")));
514+
ExecuteScalar<string>("pragma rekey = \"x'" + s + "'\"");
515+
}
516+
491517
/// <summary>
492518
/// Enable or disable extension loading.
493519
/// </summary>

tests/SQLite.Tests/SQLCipherTest.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,71 @@ 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+
var r = db.Table<TestTable> ().First ();
170+
171+
Assert.AreEqual ("Hello", r.Value);
172+
}
173+
}
174+
175+
[Test]
176+
public void ResetByteKey ()
177+
{
178+
string path;
179+
180+
var rand = new Random ();
181+
var key = new byte[32];
182+
rand.NextBytes (key);
183+
var reKey = new byte[32];
184+
rand.NextBytes (reKey);
185+
186+
using (var db = new TestDb (key: key)) {
187+
db.SetReKey (reKey);
188+
path = db.DatabasePath;
189+
190+
db.CreateTable<TestTable> ();
191+
db.Insert (new TestTable { Value = "Hello" });
192+
}
193+
194+
using (var db = new TestDb (path, key: reKey)) {
195+
var r = db.Table<TestTable> ().First ();
196+
197+
Assert.AreEqual ("Hello", r.Value);
198+
}
199+
}
200+
201+
[Test]
202+
public void ResetBadKey ()
203+
{
204+
var key = new byte[] { 42 };
205+
206+
try
207+
{
208+
using (var db = new TestDb ()) {
209+
db.SetReKey (key);
210+
}
211+
212+
Assert.Fail ("Should have thrown");
213+
}
214+
catch (ArgumentException) {
215+
}
216+
}
151217
}
152218
}

0 commit comments

Comments
 (0)