from cryptography.fernet import Fernet
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
import base64
from os import getcwd
import sqlite3
import gzip
def key_creation(password):
kdf=PBKDF2HMAC(algorithm = hashes.SHA256(), salt=b'\xfaz\xb5\xf2|\xa1z\xa9\xfe\xd1F@1\xaa\x8a\xc2', iterations=1024, length=32, backend=default_backend())
key=Fernet(base64.urlsafe_b64encode(kdf.derive(password)))
return key
def encryption(b, password):
f=key_creation(password)
safe=f.encrypt(b)
return safe
def decryption(safe, password):
f=key_creation(password)
b=f.decrypt(safe)
return b
def open_cdb(name,password):
f=gzip.open(getcwd()+name+'_crypted.sql.gz','rb')
safe=f.read()
f.close()
content=decryption(safe,password)
content=content.decode('utf-8')
con=sqlite3.connect(':memory:')
con.executescript(content)
return con
def save_cdb(con,name,password):
fp=gzip.open(getcwd()+name+'_crypted.sql.gz','wb')
b=b''
for line in con.iterdump():
b+=bytes('%s\n','utf8') % bytes(line,'utf8')
b=encryption(b,password)
fp.write(b)
fp.close()
if __name__=='__main__':
password=b'Sw0rdFish'
name='PRODUCTS'
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE PRODUCTS (ID INT PRIMARY KEY NOT NULL,\nNAME TEXT NOT NULL,\nPRICE REAL NOT NULL,\nTAXES REAL NOT NULL);')
save_cdb(conn,name,password)
conn.close()
conn = open_cdb(name,password)
cursor = conn.execute('select * from ' + name)
headers = list(map(lambda x: x[0], cursor.description))
print(headers)
for x in cursor:
for j in range(len(x)):
print(headers[j]+' ',x[j])
print('\n')
conn.close()
4条答案
按热度按时间xytpbqjk1#
我的应用程序可能有多个示例同时运行,所以我不能只加密SQLite数据库文件。我也不认为在Python中加密数据是一个好主意,因为在这种状态下,你不能在数据库中进行任何数据操作。我想到了:
1.使用前面提到的SQLCipher。我将不得不为Python编写自己的绑定并自己编译(或者支付费用)。
1.使用PyCrypto加密数据库文件。我将实现一个SQL服务器来解密数据库文件,然后处理来自客户端的请求。只要没有未完成的请求,它就会重新加密数据库。这样会比较慢,并且会使数据库处于临时解密状态。
SQLCipher我无法编译,它使用OpenSSL(对于简单的AES 128来说,这是相当庞大的)。我找到了wxSQLite3和如何separate the SQLite encryption。我得到了这个工作与最新版本的SQLite3。wxSQLite3支持AES 256。我的下一步是用修改后的sqlite3.dll编译PySQLite(Python中内置的SQLite库),并调整PySQLite以支持wxSQLite3的sqlite3.dll的扩展加密。
ktecyv1j2#
正如Frontware建议的那样,您可以使用sqlcipher。
pysqlcipher python包可以使它更容易使用,因为它使用sqlcipher代码合并来编译扩展。
这应该只是一个使用pysqlcipher的问题,就像你使用常规的sqlite.dbapi2一样,只需要设置正确的加密杂注。
67up9zun3#
SQLite数据库非常易于阅读,并且没有任何内置加密。
您是否担心有人直接访问和阅读数据库文件,或通过您的程序访问它们?
我假设是前者,因为后者实际上与数据库无关--您要问的是应用程序的安全性。
我想到了几个选择:
1.使用文件系统权限而不是加密来保护数据库。你还没有提到你的环境是什么,所以我不能说这对你是否可行,但这可能是最简单和最可靠的方法,因为你不能试图解密你不能读的东西。
1.写之前在Python中加密,阅读之后在Python中解密。相当简单,但是您将失去SQL基于集合的匹配操作的大部分功能。
1.切换到其他数据库;用户认证和许可是大多数多用户数据库的标准特征。当你发现自己遇到了一个工具的局限性时,看看其他工具可能比在当前工具中添加新功能更容易。
v64noz0r4#
您可以使用存储在内存(RAM)中的数据库,并仅保存使用加密模块获得的加密版本。然后,您可以通过解密存储的内容并在内存中重新创建数据库来访问它:
字符串