Encrypt/Hide sqlite3 database (Tkinter & Python) - python

I am currently working on a password saving application using tkinter, and I don't want the database to be visible/accesible from the computer's local storage. Is there a way to achieve this with a pre-existing python library, or do I have to pay for a service?

You can try encrypting your database. I'm fairly sure sqlite doesn't offer encryption by default, you might need an extension like SQLCipher.

If you are looking for a password verification system, you could use one-way hashes like Sha256 or a salted algorithm. If you need a password manager, you could use PyCryptoDomex to encrypt the user's password with a "master key" that the user has to remember. Then when you want to fetch a passcode, ask them for the master key again and use it to decrypt the password.

you can use Sqlite3En package or SQLCipher
Sqlite3En doc:
https://github.com/yous1010/Sqlite3En_python/tree/master
SQLCipher :
https://www.zetetic.net/sqlcipher/
A simple example for sqlite3En :
To Encript db :
from Sqlite3En import Sqlite3En
Sqlite3En.Encrypt_existing_DB_By_Password('DBfile1\\' , 'DBName.db' ,'Table_Name' , password = 'password' ) #DBfile1\\ is DB path folder
To open and connect Encrypted DB :
Memory_conn = sqlite3.connect(":memory:")
Sqlite3En.Open_Encrypted_DB_By_Password ('DBfile1\\','DBName.db','Table_Name',Memory_conn , password = 'password' )
now you can use sqlite db as usual
to select data :
Memory_conn.execute("SELECT * FROM Table_Name)
To insert new value in DB:
Memory_conn.execute("INSERT INTO Table_Name (ID,NAME,AGE) VALUES (1, 'sam', 35)");
Memory_conn.commit()
Sqlite3En.Save_Change_On_EnDB_By_Password(Memory_conn,'DBName.db','Table_Name','DBfile1\\',password = 'password' )

Related

"Not a valid password" error when reflecting an encrypted Access database

i'm beginner in sqlalchemy, i want to reflect my table in database to object, but always return invalid password, even though the password is correct. I dont understand why this happend. When i try to inspect they return my table name, so my password, connection string or on create_engine is correct.
when my database have no password is fine i can reflect it to Object, that's so weird.
but why when i reflect database with password it's error, always return "Not a valid password" ??,
My MS. Access Tbl 1
My MS. Access Tbl 2
Error in Reflect but My Table name is returned
This is my Code
because I was curious I also made a test select data, and it turned out to be successful in retrieving the data
it's returned my data and success created connection
when i add some code for testing
I think all it's correct but why cannot reflect??, Please Help.
My Reference connection_string
My Reference SqlAlchemy Automap Reflect
I have just released sqlalchemy-access version 1.1.1 to address this issue. Note that as described in Getting Connected if you want to use a pass-through ODBC connection string with an encrypted database you need to supply the password in two places:
driver = "{Microsoft Access Driver (*.mdb, *.accdb)}"
db_path = r"C:\Users\Public\test\sqlalchemy-access\gord_test.accdb"
pwd = "tiger"
connection_string = (
f"DRIVER={driver};"
f"DBQ={db_path};"
f"PWD={pwd};"
f"ExtendedAnsiSQL=1;"
)
connection_uri = (
f"access+pyodbc://admin:{pwd}#/"
f"?odbc_connect={urllib.parse.quote_plus(connection_string)}"
)
engine = sa.create_engine(connection_uri)

bcrypt different hash for same string?

I have created users in mysql with the same password then this code snippet changes the plain text passwords to a hash using bcrypt. Why is the hash different for the same string?
import mysql.connector
import bcrypt
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="........",
database="briandb",
)
mycursor = mydb.cursor()
for user in ["bob", "alice"]:
password = "ttt"
print(password)
hashed = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt())
print(hashed)
mycursor.execute(
f'UPDATE users set password = "{hashed}" where user = "{user}"'
)
mydb.commit()
You've discovered a key feature of robust password hashing: Each time you hash a password you get a different result. Why?
A different random salt (from bcrypt.gensalt() here) is used each time.
Why is this important?
If a cybercreep breaks into your system and steals your users table, they'll have your salted hashed passwords. When the hashing is done correctly, it is very difficult to recover the unsalted passwords. If they, next, break into a bank's system and steal their hashed passwords, we don't want them to be able to conclude that certain users have the same password on both systems. If they could guess that, they'd know which users to target for deeper cybercrimes.

Password not working when inserting users in Sonarqube in Python

user_password = 'admin'
salt = bcrypt.gensalt(rounds=16)
password = bcrypt.hashpw(user_password.encode('utf-8'), salt)
print(password)
sql_statementInsert = "INSERT into users
(crypted_password,login,uuid,external_login,external_identity_provider,external_id,is_root,onboarded,hash_method,active,name)
values ('{}','cosmin','1ea2ad82-b07c-11ea-b3de-0242ac130004','cosmin','sonarqube','user',false,true,'BCRYPT',true,'cosmin') on conflict (login) do nothing;".format(password.decode("utf-8"))
The generated hash for this example is: $2b$08$1KDDzD5DoVOEopOWUb0Rbu8A0FtYtI02BopFoY4Qxp5URuf3KA0s2.
I have this code which is generating some hash based on the user_password, but when trying to log in with "admin" value is not working. But when I am inserting directly the following hash in the crypted_password is working: $2a$12$uCkkXmhW5ThVK8mpBvnXOOJRLd64LJeHTeCkSuB3lfaR2N0AYBaSi
Solved this by using the good library, I needed py-bcrypt, the wrong one was bcrypt only. Also if you use the new lib you don't need to decode the password when you insert it.

How to secure a Python script SQL Server authentification

I am using a Python script to connect to a SQL Server database:
import pyodbc
import pandas
server = 'SQL'
database = 'DB_TEST'
username = 'USER'
password = 'My password'
sql='''
SELECT *
FROM [DB_TEST].[dbo].[test]
'''
cnxn = pyodbc.connect('DRIVER=SQL Server;SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
data = pandas.read_sql(sql,cnxn)
cnxn.close()
The script is launched everyday by an automatisation tools so there is no physical user.
The issue is how to replace the password field by a secure method?
The automated script is still ran by a windows user. Add this windows user to the SQL-Server users and give it the appropriate permissions, so you can use:
import pyodbc
import pandas
server = 'SQL'
database = 'DB_TEST'
sql='''
SELECT *
FROM [DB_TEST].[dbo].[test]
'''
cnxn = pyodbc.connect(
f'DRIVER=SQL Server;SERVER={server};DATABASE={database};Trusted_Connection=True;')
data = pandas.read_sql(sql,cnxn)
cnxn.close()
I am also interested in secure coding using Python .I did my own research to figure out available options, I would recommend reviewing this post as it summarize it all. Check on the listed options, and apply the one suits you better.

How to connect to a protected Sqlite3 database with Python

I created a SQLite3 database and protected it with a password ("test") thanks to the application DB browser for SQLite.
In order to connect to my database via Python, I need to provide the password but I can't figure out how to do that. I tried the following code:
conn=sqlite3.connect("mydatabase.db", Password="test")
cur=conn.cursor()
EDIT:
My SQLite3 database has been encrypted with SQLCipher (see image).
If I run the following code:
conn=sqlite3.connect("mydatabase.db")
cur=conn.cursor()
I get this error:
sqlite3.DatabaseError: file is encrypted or is not a database
How can I pass the password in order to connect with my db via Python?
EDIT 2
Here a brief summary of what I try to achieve. I am developing an application with Python 3 requiring a pre-populated database but this database needs to be protected with a password.
After extensive research, it seems complicated to connect an encrypted SQLite3 database via Python 3. A library calls pysqlcipher exists but only for Python 2.7. My next question will be maybe too broadly and I apology in advance. Is there another portable database that exists allowing me to protect it with a password and still get access to Python?
Another idea that I have in mind in order to troubleshoot my problem is to use the zipfile library. This link mentions that the zipfile module does not support encryption but it’s not clear if encryption refers to the SQLite3 database or to the zip file. The idea would be to zip my unprotected DB into a protected zip file as it seems I can do that (link).
The goal of this edit is to get new ideas on how to solve my problem. Thanks
If your database is encrypted with SqlCipher, you need to install sqlcipher in your SO
Windows: Download
Linux: sudo pacman -S sqlcipher or
sudo apt-get install sqlcipher
After you need the pysqlcipher3 lib: pip install pysqlcipher3
See: https://github.com/rigglemania/pysqlcipher3
my sample code is:
from pysqlcipher3 import dbapi2 as sqlite3
class Database(object):
def __init__(self, dbname):
self.dbname = dbname
def connDB(self):
self.conn = sqlite3.connect(self.dbname)
self.cursor = self.conn.cursor()
self.cursor.execute("PRAGMA key='mypassword'")
def createDB(self):
self.connDB()
self.cursor.execute(
'''
CREATE TABLE IF NOT EXISTS users (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
login TEXT NOT NULL,
passwd TEXT);
'''
)
self.cursor.execute(
'''
INSERT INTO users (name, login, passwd)
VALUES ("Admininstrator", "admin", "12345")
'''
)
self.conn.commit()
self.conn.close()
def queryDB(self, sql):
self.connDB()
self.cursor.execute(sql)
if sql[0:6].lower() == 'select':
result = self.cursor.fetchall()
self.conn.close()
return result
else:
self.conn.commit()
self.conn.close()
You need the SQLCipher module to read that database. The default SQLite3 module has no support for that. See https://github.com/sqlitebrowser/sqlitebrowser/wiki/Encrypted-Databases

Categories