Password protect a SQLite database with SQLite-Net Extensions [duplicate] - c#

I have to face a new little project. It will have about 7 or 9 tables, the biggest of them will grow by a max rate of 1000 rows a month.
I thought about SQLite as my db... But i will need to protect the db in case anybody wants to change data from the db
My main question is:
Is it possible password protect a sqlite db as you would do on access?
The development would be on C#, but I'm searching something free.

You can password protect a SQLite3 DB. Before doing any operations, set the password as follows.
SQLiteConnection conn = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
conn.SetPassword("password");
conn.Open();
then next time you can access it like
conn = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;Password=password;");
conn.Open();
This wont allow any GUI editor to view your data. Some editors can decrypt the DB if you provide the password. The algorithm used is RSA.
Later if you wish to change the password, use
conn.ChangePassword("new_password");
To reset or remove password, use
conn.ChangePassword(String.Empty);

You can use the built-in encryption of the sqlite .net provider (System.Data.SQLite). See more details at http://web.archive.org/web/20070813071554/http://sqlite.phxsoftware.com/forums/t/130.aspx
To encrypt an existing unencrypted database, or to change the password of an encrypted database, open the database and then use the ChangePassword() function of SQLiteConnection:
// Opens an unencrypted database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
// Encrypts the database. The connection remains valid and usable afterwards.
cnn.ChangePassword("mypassword");
To decrypt an existing encrypted database call ChangePassword() with a NULL or "" password:
// Opens an encrypted database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3;Password=mypassword");
cnn.Open();
// Removes the encryption on an encrypted database.
cnn.ChangePassword(null);
To open an existing encrypted database, or to create a new encrypted database, specify a password in the ConnectionString as shown in the previous example, or call the SetPassword() function before opening a new SQLiteConnection. Passwords specified in the ConnectionString must be cleartext, but passwords supplied in the SetPassword() function may be binary byte arrays.
// Opens an encrypted database by calling SetPassword()
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.SetPassword(new byte[] { 0xFF, 0xEE, 0xDD, 0x10, 0x20, 0x30 });
cnn.Open();
// The connection is now usable
By default, the ATTACH keyword will use the same encryption key as the main database when attaching another database file to an existing connection. To change this behavior, you use the KEY modifier as follows:
If you are attaching an encrypted database using a cleartext password:
// Attach to a database using a different key than the main database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY 'mypassword'", cnn);
cmd.ExecuteNonQuery();
To attach an encrypted database using a binary password:
// Attach to a database encrypted with a binary key
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY X'FFEEDD102030'", cnn);
cmd.ExecuteNonQuery();

Use SQLCipher, it's an opensource extension for SQLite that provides transparent 256-bit AES encryption of database files. http://sqlcipher.net

You can encrypt your SQLite database with the SEE addon. This way you prevent unauthorized access/modification.
Quoting SQLite documentation:
The SQLite Encryption Extension (SEE) is an enhanced version of SQLite that encrypts database files using 128-bit or 256-Bit AES to help prevent unauthorized access or modification. The entire database file is encrypted so that to an outside observer, the database file appears to contain white noise. There is nothing that identifies the file as an SQLite database.
You can find more info about this addon in this link.

One option would be VistaDB. They allow databases (or even tables) to be password protected (and optionally encrypted).

If you use FluentNHibernate you can use following configuration code:
private ISessionFactory createSessionFactory()
{
return Fluently.Configure()
.Database(SQLiteConfiguration.Standard.UsingFileWithPassword(filename, password))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<DBManager>())
.ExposeConfiguration(this.buildSchema)
.BuildSessionFactory();
}
private void buildSchema(Configuration config)
{
if (filename_not_exists == true)
{
new SchemaExport(config).Create(false, true);
}
}
Method UsingFileWithPassword(filename, password) encrypts a database file and sets password.
It runs only if the new database file is created. The old one not encrypted fails when is opened with this method.

I know this is an old question but wouldn't the simple solution be to just protect the file at the OS level? Just prevent the users from accessing the file and then they shouldn't be able to touch it. This is just a guess and I'm not sure if this is an ideal solution.

Why do you need to encrypt the database? The user could easily disassemble your program and figure out the key. If you're encrypting it for network transfer, then consider using PGP instead of squeezing an encryption layer into a database layer.

Related

Set password in sqlite .db3 file in xamarin forms [duplicate]

I have to face a new little project. It will have about 7 or 9 tables, the biggest of them will grow by a max rate of 1000 rows a month.
I thought about SQLite as my db... But i will need to protect the db in case anybody wants to change data from the db
My main question is:
Is it possible password protect a sqlite db as you would do on access?
The development would be on C#, but I'm searching something free.
You can password protect a SQLite3 DB. Before doing any operations, set the password as follows.
SQLiteConnection conn = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
conn.SetPassword("password");
conn.Open();
then next time you can access it like
conn = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;Password=password;");
conn.Open();
This wont allow any GUI editor to view your data. Some editors can decrypt the DB if you provide the password. The algorithm used is RSA.
Later if you wish to change the password, use
conn.ChangePassword("new_password");
To reset or remove password, use
conn.ChangePassword(String.Empty);
You can use the built-in encryption of the sqlite .net provider (System.Data.SQLite). See more details at http://web.archive.org/web/20070813071554/http://sqlite.phxsoftware.com/forums/t/130.aspx
To encrypt an existing unencrypted database, or to change the password of an encrypted database, open the database and then use the ChangePassword() function of SQLiteConnection:
// Opens an unencrypted database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
// Encrypts the database. The connection remains valid and usable afterwards.
cnn.ChangePassword("mypassword");
To decrypt an existing encrypted database call ChangePassword() with a NULL or "" password:
// Opens an encrypted database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3;Password=mypassword");
cnn.Open();
// Removes the encryption on an encrypted database.
cnn.ChangePassword(null);
To open an existing encrypted database, or to create a new encrypted database, specify a password in the ConnectionString as shown in the previous example, or call the SetPassword() function before opening a new SQLiteConnection. Passwords specified in the ConnectionString must be cleartext, but passwords supplied in the SetPassword() function may be binary byte arrays.
// Opens an encrypted database by calling SetPassword()
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.SetPassword(new byte[] { 0xFF, 0xEE, 0xDD, 0x10, 0x20, 0x30 });
cnn.Open();
// The connection is now usable
By default, the ATTACH keyword will use the same encryption key as the main database when attaching another database file to an existing connection. To change this behavior, you use the KEY modifier as follows:
If you are attaching an encrypted database using a cleartext password:
// Attach to a database using a different key than the main database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY 'mypassword'", cnn);
cmd.ExecuteNonQuery();
To attach an encrypted database using a binary password:
// Attach to a database encrypted with a binary key
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY X'FFEEDD102030'", cnn);
cmd.ExecuteNonQuery();
Use SQLCipher, it's an opensource extension for SQLite that provides transparent 256-bit AES encryption of database files. http://sqlcipher.net
You can encrypt your SQLite database with the SEE addon. This way you prevent unauthorized access/modification.
Quoting SQLite documentation:
The SQLite Encryption Extension (SEE) is an enhanced version of SQLite that encrypts database files using 128-bit or 256-Bit AES to help prevent unauthorized access or modification. The entire database file is encrypted so that to an outside observer, the database file appears to contain white noise. There is nothing that identifies the file as an SQLite database.
You can find more info about this addon in this link.
One option would be VistaDB. They allow databases (or even tables) to be password protected (and optionally encrypted).
If you use FluentNHibernate you can use following configuration code:
private ISessionFactory createSessionFactory()
{
return Fluently.Configure()
.Database(SQLiteConfiguration.Standard.UsingFileWithPassword(filename, password))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<DBManager>())
.ExposeConfiguration(this.buildSchema)
.BuildSessionFactory();
}
private void buildSchema(Configuration config)
{
if (filename_not_exists == true)
{
new SchemaExport(config).Create(false, true);
}
}
Method UsingFileWithPassword(filename, password) encrypts a database file and sets password.
It runs only if the new database file is created. The old one not encrypted fails when is opened with this method.
I know this is an old question but wouldn't the simple solution be to just protect the file at the OS level? Just prevent the users from accessing the file and then they shouldn't be able to touch it. This is just a guess and I'm not sure if this is an ideal solution.
Why do you need to encrypt the database? The user could easily disassemble your program and figure out the key. If you're encrypting it for network transfer, then consider using PGP instead of squeezing an encryption layer into a database layer.

Can I decrypt a password with c#, that was encrypted with PASSWORD_BCRYPT in php?

I am not sure if I can decrypt passwords with c#, that i stored in a mysql database. I encrypted these passwords in php using PASSWORD_BCRYPT.
And if it is possible how can I do it? Sorry but i'm a beginner and I didn't find any help on the internet. This is the piece of code I used to encrypt my passwords.
$passwort = $con->real_escape_string($_POST['passwort']);
$hash = password_hash($passwort, PASSWORD_BCRYPT);
After reading the comments I tried doing so in c# but it always says wrong password
string email = textBox1.Text;
string password = textBox2.Text;
string passwordHash = BCrypt.Net.BCrypt.HashPassword(password);
MessageBox.Show(passwordHash);
MySqlConnection conn = new MySqlConnection("datasource=127.0.0.1;port=3306;username=root;password=CIAO6CIAO6;database=kontoprogramm");
int i = 0;
conn.Open();
MySqlCommand cmd = new MySqlCommand("select KLPPassword from tklassenlehrpersonen where KLPEmail = '" + email + "' and KLPPassword = '" + passwordHash + "'", conn);
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
i = Convert.ToInt32(dt.Rows.Count.ToString());
if (i == 0)
{
MessageBox.Show("Falsche Email oder Kennwort!");
}
else
{
MessageBox.Show("Angemeldet!");
}
Can somebody please help me?
You cannot search for a hash in the database, because of the salt, instead search by username only and take the stored hash for verification. This answer shows how to do it in PHP, though the principle is the same.
And don't escape the user input before calling password_hash() this calls for trouble.
First of all, you cannot decrypt, only if you effort to troubleshooting and hack the password decryption, for example, using Brute Force technique etc, because finally result from PHP by password_hash function is generates a hashed password, hash result. By the hash primary concept, cannot be reversible, but been comparable.
You may compare password hashs using PHP function password_verify (comparing stored hash from database with the inputed password from your C# Application). If your requirement is really decrypt, it's need to change the focus of your post, re-think to troubleshooting and hack the password decryption, for example, using Brute Force technique etc.
Now, let's go to solution: you have two ways:
a) Create an PHP WebService parameterized with the "Clear Text" as input parameter, and get the output result as a encrypted text password; the core of Web Service (in PHP) uses the password_hash with PASSWORD_BCRYPT option, to encrypt. After, your C# code consumes the encrypted data and compare this output hash with stored hash from Database; however, this alternative needs to invest many efforts in security at WebServer and WebService layers. For example, your C# code consuming this PHP Web Service as code bellow:
WebClient webclient = new WebClient();
webclient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webclient_DownloadStringCompleted);
webclient.DownloadStringAsync(new Uri("http://ws.phpurl.com/?password=stackoverflow#12345"));
void webclient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
string phpWsEncryptedPass = e.Result;
string databaseEncryptedPass = //TO DO: query Database
//using WHERE statement,
//parsing 'phpWsEncryptedPass' as parameter;
}
b) OR, download the binaries of the respective PHP version for Windows that you work'on, understand these DLLs methods using a DLL Reflector application (for example dotPeek) and use C# Interop features to import the DLL thta have the password_hash and password_verify to consume this in your C# code; you need to make efforts to open the DLL, to get the correctly methods declaration. Note: this way is suggest because the Core of PHP writted in C/C++ and a C# code can be consume the DLL of PHP for Windows binaries, this code bellow has an example to do this:
[DllImport(#"C:\ProgramFiles\PHP\php_mbstring.dll", CharSet = CharSet.Unicode)]
internal static extern IntPtr password_hash(string clearTextpassword, int option)
[DllImport(#"C:\ProgramFiles\PHP\php_mbstring.dll", CharSet = CharSet.Unicode)]
internal static extern bool password_verify(string clearTextpassword, string hash)
That's all.

C# MD5CryptoServiceProvider

I am currently converting a legacy ASP.NET 1.1 application into a .NET 4 MVC 3 application.
I am looking at the password encryption and a routine was written in the old code to use the MD5CryptoServiceProvider.
private string EncryptText(string szText)
{
try
{
UTF8Encoding objEncoder = new UTF8Encoding();
MD5CryptoServiceProvider objMD5Hasher = new MD5CryptoServiceProvider();
Byte[] btHashedDataBytes = objMD5Hasher.ComputeHash(objEncoder.GetBytes(szText));
string szReturn = objEncoder.GetString(btHashedDataBytes);
objEncoder = null;
objMD5Hasher = null;
return szReturn;
}
catch
{
return "";
}
}
I have written a quick .NET 4 console application and copied this function so I can do a comparison against the current passwords in the database (to make sure the MD5 function still gives me the same output)
string encTxt = encryptor.EncryptText("fbloggsPass12345");
using (SqlConnection conn = new SqlConnection("Server=server;Database=db;User Id=sa;Password=1111;"))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "UPDATE SiteUsers SET Token = '" + encTxt + "' WHERE PKey = 10";
if (cmd.ExecuteNonQuery() > 0)
Console.WriteLine("Updated");
else
Console.WriteLine("Failed");
}
conn.Close();
}
Console.ReadLine();
However the password in the database is currently !?MGF+&> and the output I am getting is ���!?��MGF�+&��> which when I store in the database converts to ???!???MGF?+&??>
Which I can see is almost the same, but why am I getting the ? characters
This is the first problem, at least:
string szReturn = objEncoder.GetString(btHashedDataBytes);
You're trying to use the hash as if it were UTF-8-encoded text. It's not - it's just arbitrary binary data.
If you need to convert arbitrary binary data to text, you should use something like Base64 (e.g. Convert.ToBase64String) or hex.
(Additionally, I would strongly advise you not to "handle" exceptions in the way you're doing so at the moment. Why would you want to hide problems like that? And why are you setting variables to null just before they go out of scope anyway?)
Oh, and please don't include values directly in your SQL like that - use parameterized SQL instead.
Finally, I would use a different hashing algorithm these days, particularly for passwords. Can you not use an off-the-shelf system for authentication, which is actually developed by security experts? Security is difficult: we'd all be better off leaving it to the relatively few people who know how to do it right :) See comments for more suggestions.
The standard technique for low impact upgrading is using the old hash as input for the new hashing scheme. This works pretty well with normal MD5 hashes.
Unfortunately for you, you were sending the binary hash through a non binary safe encoding (UTF8). This replaced every second character by 0xFFFD, effectively halving the output size to 64 bits. This weakens an upgraded scheme considerably but not fatally.
I'd upgrade the existing hashes to PBKDF2(legacyHash, salt), then on user login replace the hash with a new hash PBKDF2(password, salt) that doesn't depend on the legacy scheme. After a few months trigger a password reset for all users who did not login yet, getting rid of the legacy hash based passwords.
For the new scheme, I'd go with PBKDF2-SHA-1 which is implemented in the Rfc2898DeriveBytes Class. Use sufficient iterations, at least 10000.

sqlite c# generated open on as3

I have a DB that is generated by C# code, and when i'm creating it I use the connection string I use
new SQLiteConnection("Data Source=" + dbPath + ";Version=3;New=False;Compress=True;Password=1234");
The database is created with success but when I download it to my computer and try to read in on adobe air I can't seem to open the database. The only way of passing password to the connection is passing it by bytearray but I can't get it right.
My as3 code is like this:
_connection = new SQLConnection();
_connection.addEventListener(SQLEvent.OPEN, onDatabaseOpen);
_connection.addEventListener(SQLEvent.CLOSE, onDatabaseClose);
_connection.addEventListener(SQLErrorEvent.ERROR, onDatabaseError);
var ba:ByteArray = new ByteArray();
ba.writeMultiByte("1234","unicode");
_connection.open(_mydatabaseFile,SQLMode.READ,false,1024,ba);
It always gets an error because of the length of the bytearray.
Edit:
I forgot to mention, if i don't put the password on the conection i can open the database without problem using just _connection.open(_mydatabaseFile)
Thanks in advance
Alex

Creating a Login Screen, WPF, how to store usernames and passwords

For my application, i have a part where all the settings are. This can be accessed by clicking the settings button.
Now, what i want to do, i before it pops up the settings, add a small login screen, so that only an admin can change the settings.
At first i thought of keeping it very simple by just add a default username "Admin" and password "AdminPass"
This i would just check if the userinput is the same as what it should be in code, and if it is the dame it will continue.
But there is a downside at this, the username and pass are hardcoded inside, so it cant be changed anymore within the application. (unless i would do it in the settings, but that is just a xml that can be read outside the app, and thus not a correct solution).
So i wonder, what would be the best approach for this problem ? So that after logging in the first time with the default, the admin can change the admin pass, and this is saved into the application (and thus is saved after the application restarts).
One way could be to get the hash of password and store in a text file. Then when user enter the password, hash it. Match with the hash stored in the text file. If it matches you can allow login.
Similarly if user decides to change the password, replace the old hash with the new one
You can use this code for hashing the password
public static string EncodePassword(string password)
{ byte[] bytes = Encoding.Unicode.GetBytes(password);
byte[] inArray = HashAlgorithm.Create("SHA1").ComputeHash(bytes);
return Convert.ToBase64String(inArray);
}
You can also save this information in application configuration file
Best solution if possible would be to create a database table for users. This will allow you to change passwords and have multiple user accounts for your application.
If for some reason you don't want to use a database system and we are not talking for a high security application, then an encrypted password could be saved in your xml file in a non reversible encryption such as the MD5.
System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] data = System.Text.Encoding.ASCII.GetBytes(yourPassword);
data = x.ComputeHash(data);
String md5Hash = System.Text.Encoding.ASCII.GetString(data);

Categories

Resources