Decrypting the Encrypted Database


#1

Hi,

I am using couchbasel lite. I am able to encrypt the database using the below code. I am using .net 4.5.2. and C#.

SymmetricKey _key = new SymmetricKey(“password123456”);
var options = new DatabaseOptions
{
EncryptionKey = _key,
Create = true,
StorageType = StorageEngineTypes.SQLite,
ReadOnly = false
};
var database = manager.OpenDatabase(“app”, options);

but unable to decrypt the database. using the key generated above.

I have dowloaded the nuget packge for SQLCipher as mentioned in the guide and registered it at the lauch of the application.

Please let me now know how to decrypt the database. Appreciate you help.

Thanks
Pramod


#2

Does it fail in the same way if you create a new database and the close and reopen it? What you have shown should work assuming the password is correct (keep in mind it will fail the same way if you try to open a non-encrypted database like this).


#3

Hi borrden,

Thanks for the response.
I am attaching a sample code. When there are 3 simple button for encryption, decryption and query.

  1. After the decrypt the database using the following code
    SymmetricKey _key = new SymmetricKey(“password123456”);
    var options = new DatabaseOptions
    {
    EncryptionKey = _key,
    Create = true,
    StorageType = StorageEngineTypes.SQLite,
    ReadOnly = false
    };
    var database = manager.OpenDatabase(“app”, options);

and try to open the database in sqlite express I get the error “file is encrypted or is not a database SQL Statement: select name from sqlite_master limit 0, 0.”

Please let me know where i am going wrong. Any help in this regard is appreciated.
Please find the code below:
using System;
using System.Collections.Generic;
using System.Windows;
using Couchbase.Lite;
using Couchbase.Lite.Store;

namespace POC_EncryptCouchDbLiteWPF
{
///


/// Interaction logic for MainWindow.xaml
///

public partial class MainWindow : Window
{
private Manager _manager = Manager.SharedInstance;
SymmetricKey _key = new SymmetricKey(“password123456”);
private string documentId=string.Empty;
public MainWindow()
{
InitializeComponent();
Couchbase.Lite.Storage.SQLCipher.Plugin.Register();
}

    private void EncryptDatabase_Click(object sender, RoutedEventArgs e)
    {
        richTextBox.AppendText("Hexadecimal    " + _key.HexData + "\r");
        var options = new DatabaseOptions
        {
            EncryptionKey = _key,
            Create = true,
            StorageType = StorageEngineTypes.SQLite,
            ReadOnly = false
        };
        var database = _manager.OpenDatabase("app", options);
        richTextBox.AppendText($"Database created" + database.Name + "\r");

        Dictionary<string, object> properties = new Dictionary<string, object>
        {
            { "title", "Couchbase Mobile"},
            { "sdk", "C#" }
        };

        var document = database.CreateDocument();
        document.PutProperties(properties);
        documentId = document.Id;
        richTextBox.AppendText($"Document ID :: {document.Id}" + "\r");
        richTextBox.AppendText($"Learning {document.GetProperty("title")} with {document.GetProperty("sdk")}" + "\r");
    }

    private void DecryptDatabase_Click(object sender, RoutedEventArgs e)
    {
        richTextBox.AppendText("Decrypting data");
        richTextBox.AppendText("Hexadecimal    " + _key.HexData + "\r");

        var options = new DatabaseOptions
        {
            EncryptionKey = _key,
            StorageType = StorageEngineTypes.SQLite,
            ReadOnly = false
        };
      
        var database = _manager.OpenDatabase("app", options);
        //database.ChangeEncryptionKey(new SymmetricKey());
    }

    private void QueryDatabase_Click(object sender, RoutedEventArgs e)
    {
        var database = _manager.GetDatabase("app");
        var doc = database.GetDocument(documentId);
        doc.GetProperty("title");

        richTextBox.AppendText($"Document ID :: {doc.Id}" + "\r");
        richTextBox.AppendText($"Learning {doc.GetProperty("title")} with {doc.GetProperty("sdk")}" + "\r");
    }
}

}

Thanks
Pramod Gujjar


#4

These function names are a bit suspicious. They don’t match up with what the code is doing:

EncryptDatabase will open a database with the given key, and create it encrypted if it does not exist
DecryptDatabase will open a database with the given key (if you want to remove the key, set the encryption key to null after it is open)
QueryDatabase will open the database with the same key that was used to open a currently open database of the same name (it is safer to use OpenDatabase) and create it if it does not exist (with no encryption).

So if you query first, you will end up with a non-encrypted DB, which will fail to open with encrypt OR decrypt. Can you confirm the order of operations you are using?


#5

Hi Borrden,

As per your suggestion in the earlier replay, Please share me a sample code to remove the key and set the encryption key to null after it is open.

Thanks
Pramod Gujjar.


#6

It’s the same as your code (the commented line)

database.ChangeEncryptionKey(null);


#7

When I set database.ChangeEncryptionKey(null), I get the below exception. Please let me know how to get around it.

Couchbase.Lite.CouchbaseLiteException was unhandled
HResult=-2146233088
Message=Error cleaning up step #3
Source=Couchbase.Lite
StackTrace:
at Couchbase.Lite.Util.AtomicAction.CleanUp()
at Couchbase.Lite.Database.ChangeEncryptionKey(SymmetricKey newKey)
at POC_EncryptCouchDbLiteWPF.MainWindow.DecryptDatabase_Click(Object sender, RoutedEventArgs e) in D:\POC EncryptCouchDbLite\POC EncryptCouchDbLiteWPF\POC EncryptCouchDbLiteWPF\MainWindow.xaml.cs:line 63
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.Primitives.ButtonBase.OnClick()
at System.Windows.Controls.Button.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at POC_EncryptCouchDbLiteWPF.App.Main() in D:\POC EncryptCouchDbLite\POC EncryptCouchDbLiteWPF\POC EncryptCouchDbLiteWPF\obj\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
HResult=-2146233088
Message=Decryption of database failed
Source=Couchbase.Lite.Storage.SQLCipher
StackTrace:
at Couchbase.Lite.Storage.SQLCipher.SqlitePCLRawStorageEngine.OpenRWConnection(Boolean forceRo)
at Couchbase.Lite.Storage.SQLCipher.SqlitePCLRawStorageEngine.Open(String path, Boolean readOnly, String schema, SymmetricKey encryptionKey)
at Couchbase.Lite.Storage.SQLCipher.SqliteCouchStore.Open()
at Couchbase.Lite.Storage.SQLCipher.SqliteCouchStore.c__AnonStoreyB.<>m__6()
at Couchbase.Lite.Util.AtomicAction.CleanUp()
InnerException:


#8

Hi,

Please tell me how disable encryption, I am getting exception in CouchbaseLite when i set ChangeEncryptionKey to null after opening the database. Please see my previous post for the stack trace and the exception.


#9

I realized that the unit test suite doesn’t cover this situation, and when I added it onto an existing test I ran into the same issue. I filed it and already put in a fix. This will be in build 1.4.1-66 or above on the CI server if you are interested in picking it up for verification.


#10

Thanks for putting in the fix. Apologies for the delayed response. Does the latest version 1.4.1-67 contain the fix as i was not able to find 1.4.1-66 version on the CI Server.


#11

Yes, any time I say a version it means “that version or higher.” A skipped number means that something went wrong in the build server and we had to try again (sometimes many times…)


#12

Thanks. Appreciate your help.