python中的加密文件或数据库

8 python sqlite encryption

我有一个sqlite3数据库,我在python中插入/选择.该应用程序工作得很好,但我想调整它,所以没有密码,没有人可以从数据库中读取.我怎么能在python中做到这一点?请注意我不知道从哪里开始.

小智 10

您可以使用SQLCipher.

http://sqlcipher.net/

SQLite的开源完整数据库加密

SQLCipher是一个SQLite扩展,为数据库文件提供透明的256位AES加密.页面在写入磁盘之前已加密,在回读时会被解密.由于占地面积小,性能优异,因此非常适合保护嵌入式应用数据库,非常适合移动开发.

  1. 在许多操作上加密,只需5-15%的开销即可实现快速性能
  2. 数据库文件中100%的数据都是加密的使用良好的安全实践(CBC模式,密钥派生)
  3. 零配置和应用级加密广泛平台
  4. 支持:适用于Windows,Linux,iPhone/iOS上的C/C++,Obj-C,QT,Win32/.NET,Java,Python,Ruby等...

  • 究竟是如何让它从Python开始工作的? (11认同)
  • 它是开源的,所以它是免费的,对吗?然而,你可以“购买”它。你在买什么'?(另外,和 Michael 有同样的问题,“人们究竟是如何从 Python 让它工作的?”) (2认同)

she*_*ter 6

我有同样的问题。我的应用程序可能同时运行多个实例。因此,我不能只加密 sqlite db 文件并完成它。我也不相信在 python 中加密数据是一个好主意,因为在这种状态下你不能在数据库中进行任何严重的数据操作。

考虑到这些限制,我提出了以下两种解决方案:

  1. 使用前面提到的 SQLCipher。我在这里看到的问题是,我必须为 Python 编写自己的绑定,然后自己编译(或支付费用)。在任何一种情况下,我都可能会这样做,因为这对其他 Python 开发人员来说是一个很好的解决方案。如果我成功了,我会发回解决方案。

  2. 如果选项 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 上发布最终的代码库和构建说明。

  • 不幸的是,这个项目失败了,我再也没有回来。 (2认同)

小智 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)


Tim*_*her 3

SQLite 数据库非常易于人类阅读,并且没有任何内置加密。

您是否担心有人直接访问和读取数据库文件,或通过您的程序访问它们?

我假设是前者,因为后者实际上与数据库无关——您要问的是应用程序的安全性。

我想到了几个选项:

  1. 使用文件系统权限而不是加密来保护数据库。您没有提到您的环境是什么,所以我不能说这是否适合您,但这可能是最简单和最可靠的方法,因为您无法尝试解密您无法读取的内容。
  2. 写入前用Python加密,读取后用Python解密。相当简单,但是您会失去 SQL 基于集合的匹配操作的大部分功能。
  3. 切换到另一个数据库;用户身份验证和权限是大多数多用户数据库的标准功能。当您发现自己遇到某个工具的限制时,查看其他工具可能比在当前工具中添加新功能更容易。