我有一个sqlite3数据库,我在python中插入/选择.该应用程序工作得很好,但我想调整它,所以没有密码,没有人可以从数据库中读取.我怎么能在python中做到这一点?请注意我不知道从哪里开始.
小智 10
您可以使用SQLCipher.
SQLite的开源完整数据库加密
SQLCipher是一个SQLite扩展,为数据库文件提供透明的256位AES加密.页面在写入磁盘之前已加密,在回读时会被解密.由于占地面积小,性能优异,因此非常适合保护嵌入式应用数据库,非常适合移动开发.
我有同样的问题。我的应用程序可能同时运行多个实例。因此,我不能只加密 sqlite db 文件并完成它。我也不相信在 python 中加密数据是一个好主意,因为在这种状态下你不能在数据库中进行任何严重的数据操作。
考虑到这些限制,我提出了以下两种解决方案:
使用前面提到的 SQLCipher。我在这里看到的问题是,我必须为 Python 编写自己的绑定,然后自己编译(或支付费用)。在任何一种情况下,我都可能会这样做,因为这对其他 Python 开发人员来说是一个很好的解决方案。如果我成功了,我会发回解决方案。
如果选项 1 对我来说太难,或者太耗时,我会使用这种方法。这种方法并不安全。我将使用 pycrypto 来加密数据库文件。我将实现一个 SQL“服务器”,它将解密数据库文件,然后处理来自各种客户端的请求。只要没有未完成的请求,它就会重新加密数据库。总的来说,这会更慢,并使数据库处于临时解密状态。
希望这些想法能帮助下一个人。
编辑 1/13/2013
我放弃了 SQLCipher,因为我似乎无法编译它,并且代码库正在尝试使用 OpenSSL,它虽然是一个声音库,但对于简单的 AES 128 来说是相当庞大的代码库。
我找到了另一个选项 wxSQLite3,我发现了如何分离 SQLite 加密部分:https : //github.com/shenghe/FreeSQLiteEncryption。我能够让它编译和工作(使用最新版本的 SQLite3)。wxSQLite3 还支持 AES 256,这真的很酷。我的下一步将是尝试使用修改后的 sqlite3.dll 编译 pysqlite(这是 Python 内置的 sqlite 库)。如果可行,我将调整 pysqlite 以支持 wxSQLite3 的 sqlite3.dll 的扩展加密部分。无论如何,我会尝试用我的结果更新这个线程,如果成功,我会在 Github 上发布最终的代码库和构建说明。
小智 5
正如 Frontware 所建议的,您可以使用 sqlcipher。
pysqlcipher python 包可以使其更易于使用,因为它使用 sqlcipher 代码合并来编译扩展。
这应该只是使用 pysqlcipher 的问题,就像使用常规 sqlite.dbapi2 一样,只需设置正确的加密编译指示即可。
小智 5
您可以使用存储在内存 (RAM) 中的数据库,并且仅保存使用加密模块获得的加密版本。然后,您可以通过解密存储的内容并在内存中重新创建数据库来访问它:
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()
Run Code Online (Sandbox Code Playgroud)
SQLite 数据库非常易于人类阅读,并且没有任何内置加密。
您是否担心有人直接访问和读取数据库文件,或通过您的程序访问它们?
我假设是前者,因为后者实际上与数据库无关——您要问的是应用程序的安全性。
我想到了几个选项: