代码之家  ›  专栏  ›  技术社区  ›  A.J. Uppal

如何在python中存储帐户信息,以便以后可以访问?

  •  -2
  • A.J. Uppal  · 技术社区  · 11 年前

    python中一个常见的问题是如何存储用户信息,如用户名、密码和游戏中的钱,以便以后可以访问。这可能吗?如果是,是如何做到的?

    2 回复  |  直到 9 年前
        1
  •  1
  •   Roland Smith    11 年前

    这取决于安全对您的重要性。

    通常,如果存储的信息和读取信息的程序在同一台机器上可用,则不可能安全地存储数据。 在这种情况下,安全的手段主要是保护它免受操纵。

    只要攻击者能够研究程序以了解它如何存储信息,他就可以读取信息。你能做的最好的就是混淆它。

    要验证用户输入的凭据,您可以不存储用户名和密码本身,而是存储它们的哈希值。哈希函数是不可逆的,因此无法撤消。

    In [1]: import hashlib
    
    In [2]: data = {'user': hashlib.sha256('Roland').hexdigest(), 'password' : hashlib.sha256('mysecretpassword').hexdigest(), 'amount': 273}
    
    In [3]: data
    Out[3]: {'amount': 273, 'password': '94aefb8be78b2b7c344d11d1ba8a79ef087eceb19150881f69460b8772753263', 'user': 'a1ef7bf9b9098c49c8aa4e6e8b42b199762a55f85ec6ad215a76045088276fcc'}
    

    要使用它,您需要对用户输入进行散列,并将其与存储的散列进行比较。

    In [45]: hashlib.sha256('Ronald').hexdigest() == data['user']
    Out[45]: False
    
    In [46]: hashlib.sha256('Roland').hexdigest() == data['user']
    Out[46]: True
    

    存储数据的一种灵活方式是使用json。通过这种方式,您可以轻松地保存和加载字典或字典列表。

    In [4]: import json
    
    In [5]: datastring = json.dumps(data)
    
    In [6]: datastring
    Out[6]: '{"amount": 273, "password": "94aefb8be78b2b7c344d11d1ba8a79ef087eceb19150881f69460b8772753263", "user": "a1ef7bf9b9098c49c8aa4e6e8b42b199762a55f85ec6ad215a76045088276fcc"}'
    
    In [7]: json.loads(datastring)
    Out[7]: {u'amount': 273, u'password': u'94aefb8be78b2b7c344d11d1ba8a79ef087eceb19150881f69460b8772753263', u'user': u'a1ef7bf9b9098c49c8aa4e6e8b42b199762a55f85ec6ad215a76045088276fcc'}
    

    请注意,虽然用户名和密码不可读,但金额是可读的,可以在磁盘上更改。问题是,您无法对金额进行哈希,因为您无法对其进行非共享。

    例如,您可以压缩数据以使其模糊。

    In [8]: import bz2
    
    In [9]: bz2.compress(datastring)
    Out[9]: 'BZh91AY&SY\xbf\x86\x82)\x00\x00T\x99\x80P\x04\x7f\xf0?\x03\xde\x8a \x00\x8a\x88\xa9\xf8\x93\xd4\xf4\xa7\xe4\xc9!\xfa\x88\xd0\n4\xf4\x91\xfa\x81\x00\x01\xa3\x00`:\x9e\xdey?\xa2\x1e\x12\xf3\xbeC\xb9\xb1f\x80\xf6\xaa6\xc5[\xad\\\xac\xf3e\xa8\xb0\xdf:!{\xe5\x10\xae\xae\x07p\xc0\xc3\x14*.\xa0j$\xda\t\xb9K\xa7\\\x81\x11\xa1@\x06\xc4C\x8b\xae\xbc\xc2\xa0\x0e\x1e#H\x91%\xd1\n\x9drS-\x97e_lb\x97C\x0fm\xe6\xb0\xb2\xc2V\x10\x7f\xc9\xf8\xbb\x92)\xc2\x84\x85\xfc4\x11H'
    
    In [10]: len(bz2.compress(datastring))
    Out[10]: 157
    
    In [11]: len(datastring)
    Out[11]: 171
    
    In [12]: compressed = bz2.compress(datastring)
    

    压缩数据乍一看是不可读的。

    读取数据仍然非常简单:

    In [13]: json.loads(bz2.decompress(compressed))
    Out[13]: {u'amount': 273, u'password': u'94aefb8be78b2b7c344d11d1ba8a79ef087eceb19150881f69460b8772753263', u'user': u'a1ef7bf9b9098c49c8aa4e6e8b42b199762a55f85ec6ad215a76045088276fcc'}
    

    但是,攻击者可以使用例如 file UNIX上用于确定存储数据的性质的命令;

    In [18]: with open('data.bin', 'w') as storage:
       ....:     storage.write(compressed)
       ....:     
    
    > file data.bin 
    data.bin: bzip2 compressed data, block size = 900k
    
        2
  •  1
  •   user3367523 user3367523    11 年前

    尝试泡菜和SQLite。。。这两种情况下都有效:)