【问题标题】:Inserting cipher text into mysql using python使用python将密文插入mysql
【发布时间】:2019-08-06 02:51:42
【问题描述】:

所以我有一个程序,它将使用 AES 加密字符串并生成以字节 [] 为单位的密码。 我希望将此密码存储在 mysql 数据库中。 我发现我们可以在 mysql 中使用 VARBINARY 数据类型来做到这一点。

我们可以通过哪些方式实现这一目标。

这是我的尝试:

import ast
import mysql.connector
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes



def encrypt(key, msg):
    iv = get_random_bytes(16)
    cipher = AES.new(key, AES.MODE_CFB, iv)
    ciphertext = cipher.encrypt(msg)    # Use the right method here
    db = iv + ciphertext
    print(db)
    cursor.executemany(sql_para_query,db)
    print(cursor.fetchone())
    connection.commit()
    return iv + ciphertext


def decrypt(key, ciphertext):
    iv = ciphertext[:16]
    ciphertext = ciphertext[16:]
    cipher = AES.new(key, AES.MODE_CFB, iv)
    msg = cipher.decrypt(ciphertext)
    return msg.decode("utf-8")


if __name__ == "__main__":
    connection = mysql.connector.connect(host = "localhost", database = "test_db", user = "sann", password = "userpass",use_pure=True)
    cursor = connection.cursor(prepared = True)
    sql_para_query = """insert into test1 values(UNHEX(%s)) """
    ed = input("(e)ncrypt or (d)ecrypt: ")
    key = str(1234567899876543)
    if ed == "e":
        msg = input("message: ")
        s= encrypt(key, msg)
        print("Encrypted message: ", s)
        file = open("e_tmp","wb+")
        file.write(s)
        print(type(s))

    elif ed == "d":
        #smsg = input("encrypted message: ")
        #file = open("e_tmp","rb")
        #smsg = file.read()
        #print(type(smsg))
        sql_para_query = """select * from test1"""
        cursor.execute(sql_para_query)
        row = cursor.fetchone()
        print(row)
        #smsg = str(smsg)
        #msg = ast.literal_eval(smsg)
        #print(msg)
        #print(type(msg))
        #s=decrypt(key, msg)
        #print("Decrypted message: ", s)
        #print(type(s))

我得到的错误:

Traceback(最近一次调用最后一次):文件 "/home/mr_pool/.local/lib/python3.6/site-packages/mysql/connector/cursor.py", 第 1233 行,在 executemany 中 self.execute(操作,参数)文件“/home/mr_pool/.local/lib/python3.6/site-packages/mysql/connector/cursor.py”, 第 1207 行,执行中 elif len(self._prepared['parameters']) != len(params): TypeError: object of type 'int' has no len()

在处理上述异常的过程中,又发生了一个异常:

Traceback(最近一次调用最后一次):文件“tmp1.py”,第 36 行,在 s= encrypt(key, msg) 文件“tmp1.py”,第 14 行,在 encrypt cursor.executemany(sql_para_query,db) 文件 "/home/mr_pool/.local/lib/python3.6/site-packages/mysql/connector/cursor.py", 第 1239 行,在 executemany 中 "执行操作失败;{error}".format(error=err)) mysql.connector.errors.InterfaceError: 执行操作失败; 'int' 类型的对象没有 len()

也欢迎任何其他选择。

我的最终目标是将加密文本存储在数据库中。

【问题讨论】:

    标签: mysql python-3.x cryptography


    【解决方案1】:

    我重现了您的错误,但您的代码中似乎有更多错误。 键和消息都是字符串,因此出现此错误:

    TypeError: Object type <class 'str'> cannot be passed to C code
    

    我通过将它们编码为 utf-8 来修复:

    # line 38:
    key = str(1234567899876543).encode("utf8")
    # .... line 41:
    s= encrypt(key, msg.encode("utf8"))
    

    您的 SQL 查询中不需要 UNHEX 函数,因为我们将数据作为 VARBINARY 输入。您可以将您的声明更改为:

    """insert into test1 values(%s) """
    

    函数 executemany() 可以替换为 execute(),因为您只输入一个语句。不过我会写出同时使用execute或executemany的解决方案。

    用 execute() 插入:

    来自文档:

    cursor.execute(操作, params=None, multi=False)

    iterator = cursor.execute(operation, params=None, multi=True)

    此方法执行给定的数据库操作(查询或命令)。 元组或字典中的参数 绑定到操作中的变量。使用 %s 或 %(name)s 参数样式(即使用 format 或 pyformat 样式)指定变量。如果 multi 为 True,则 execute() 返回一个迭代器。 https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html

    所以我们只需要将 cursor.execute 行更改为:

    cursor.execute(sql_para_query, (db, ))
    

    用 executemany() 插入:

    来自文档:

    cursor.executemany(操作,seq_of_params) 此方法准备数据库操作(查询或命令)并针对在序列 seq_of_params 中找到的所有参数序列或映射执行它。 https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-executemany.html

    因此,我们需要使用您要插入的值构建一个序列。在您的情况下,只有一个值:

     cursor.executemany(sql_para_query, [(db, )])
    

    要插入多个值,您可以在序列中添加任意数量的元组。

    完整代码:

    import ast
    import mysql.connector
    from Crypto.Cipher import AES
    from Crypto.Random import get_random_bytes
    
    def encrypt(key, msg):
        iv = get_random_bytes(16)
        cipher = AES.new(key, AES.MODE_CFB, iv)
        ciphertext = cipher.encrypt(msg)    # Use the right method here
        db = iv + ciphertext
        cursor.execute(sql_para_query, (db, ))
        connection.commit()
        return iv + ciphertext
    
    
    def decrypt(key, ciphertext):
        iv = ciphertext[:16]
        ciphertext = ciphertext[16:]
        cipher = AES.new(key, AES.MODE_CFB, iv)
        msg = cipher.decrypt(ciphertext)
        return msg.decode("utf-8")
    
    
    if __name__ == "__main__":
        connection = mysql.connector.connect(host = "localhost", database = "test_db", user = "sann", password = "userpass",use_pure=True)
        cursor = connection.cursor(prepared = True)
        sql_para_query = """insert into test1 values(%s) """
        ed = input("(e)ncrypt or (d)ecrypt: ")
        key = str(1234567899876543).encode("utf8")
        if ed == "e":
            msg = input("message: ")
            s= encrypt(key, msg.encode("utf8"))
            print("Encrypted message: ", s)
            file = open("e_tmp","wb+")
            file.write(s)
            print(type(s))
    
        elif ed == "d":
            sql_para_query = """select * from test1"""
            cursor.execute(sql_para_query)
            row = cursor.fetchone()
            msg = row[0] # row is a tuple, therefore get first element of it
            print("Unencrypted message: ", msg)
            s=decrypt(key, msg)
            print("Decrypted message: ", s)
    

    输出:

    #encrypt:
    (e)ncrypt or (d)ecrypt: e
    message: this is my test message !!
    Encrypted message:  b"\x8f\xdd\xe6f\xb1\x8e\xb51\xc1'\x9d\xbf\xb5\xe1\xc7\x87\x99\x0e\xd4\xb2\x06;g\x85\xc4\xc1\xd2\x07\xb5\xc53x\xb9\xbc\x03+\xa2\x95\r4\xd1*"
    <class 'bytes'>
    #decrypt:
    (e)ncrypt or (d)ecrypt: d
    Unencrypted message:  bytearray(b"\x8f\xdd\xe6f\xb1\x8e\xb51\xc1\'\x9d\xbf\xb5\xe1\xc7\x87\x99\x0e\xd4\xb2\x06;g\x85\xc4\xc1\xd2\x07\xb5\xc53x\xb9\xbc\x03+\xa2\x95\r4\xd1*")
    Decrypted message:  this is my test message !!
    

    【讨论】:

      猜你喜欢
      • 2018-03-02
      • 2011-05-14
      • 2015-12-29
      • 1970-01-01
      • 1970-01-01
      • 2019-01-08
      • 2021-08-22
      • 2011-11-01
      • 2015-01-22
      相关资源
      最近更新 更多