1

问题

我正在用python编写一个应用程序。它处理联系人和有关一个人的其他信息。每次他/她想要执行主要操作时,我都想提示用户输入主密钥。我已经想通了。整个应用程序已准备就绪并且运行良好。但是我将主密钥存储在一个文件中。该文件以纯文本形式易于阅读。我尝试使用此功能的朋友说,如果我不应用强大的加密算法,该软件将毫无用处,因为用户只会信任该应用程序的详细信息很容易被窃取。

目标

以只能由我的程序解密(或读取)的形式存储主密钥。

其他事情

  1. 用户可以选择更改主密钥。
  2. 主密钥将仅被读取和解密一次。在程序开始时。然后它将存储在一个变量中,并从此变量中使用。
  3. 它是一个 GUI 应用程序。我正在使用 python Tkinter。

细节

请注意,数据是使用另一种加密方式存储的,这种加密方式并非不可破解,但足以存储此类信息。

我没有使用任何数据库来存储信息。

唯一要加密的数据是主密钥。它是一个长度为 7 到 80 个字符的字母数字字符串。

眼镜

1.Python 2.7
2.Tkinter 8.5
3. Linux Mint 14
4

5 回答 5

2

您不需要,甚至不需要对密码进行复杂的加密——您所描述的是密码,而不是密钥(它只是授予访问权限,它不加密数据)。当前的最佳实践是存储加密和散列的密码。也就是说,当用户创建一个新帐户并输入密码时,您会从密码加上用户名加上一个“盐”构建一个字符串(这只是一个对您网站上的每个人都相同的小字符串——这是为了阻止彩虹桌攻击)。然后你通过一个好的散列算法运行那个字符串——像 SHA1 这样的算法就可以了(即使是 MD5 也足够了,尽管有相反的报告)。你当然不需要像 AES 这样的东西。无论如何,既然你有一个哈希,你将哈希存储在数据库中,而不是密码。如果不这样做,即使是像 AES 这样的强密码也是无用的

下次用户登录时,您也这样做:将他的密码添加到用户名和 salt,对其进行散列,并将散列与存储的内容进行比较。即使在原则上,您也无法知道他的密码是什么,因此即使攻击者获取了您的数据库并知道您的算法和盐,他们也无法找到它。

于 2013-04-22T11:58:12.560 回答
1
  1. 用户选择主密钥,您对其进行加密并将加密保存到文件中。
  2. 当用户想要进行重大操作时,您会提示他们输入主密钥,然后您对他们输入的内容进行加密。
  3. 将#2 与#1 进行比较,如果它们匹配,则让用户继续。否则,你告诉用户迷路。

以可破译的形式存储主密钥

没有。如果你能破译它,黑客就能破译它。你想要一台连续工作 100 年的超级计算机无法破译的东西。根据数据的敏感程度,您可能只需要 SHA-1/SHA-2/SHA-3。见这里:维基百科

请注意,如果有人窃取了包含加密的文件的副本,并且当您的应用提示他们输入主密钥时他们输入了其中一种加密,您的应用将对加密进行加密,并且结果将不匹配任何加密文件。

于 2013-04-22T08:08:12.047 回答
1

由于您想通过密码保护您的敏感数据,因此最好使用像AES这样的“现成”对称加密算法。这样,您的数据将被高度加密(假设您正确掌握了一些参数),您甚至不需要将密码存储在磁盘上的某个位置。

PyCrypto是一个广泛使用的加密工具包,也提供 AES。了解入门的必要细节可能有点麻烦,特别是因为我能找到所有关于“如何使用 PyCrypto 进行 AES?”的示例。都有些不同(例如算法的初始化,填充)。

对于初学者,这篇博文将为您提供一些解释和代码片段。(注意:那里提供的代码将解密(=实际)数据写入文件,这可能是一个严重的风险。在您了解代码的工作原理之后,您可以修改代码以便将解密的数据存储为字符串和使用您已有的应用程序代码从中读取内容。)

于 2013-04-22T10:09:09.593 回答
1

正如您在评论中的问题所建议的那样。这是一种与您当前正在构建的模式略有不同的模式。

首先,如果您对某些内容进行加密,请使用公认的和众所周知的工具进行加密。现在的经典是AES。这是原始密码,对 16 字节块执行加密。它只需要一个长度为 128、192 或 256 位的密钥。
实际上,底层密码支持的长度比这更多,但是该算法已经在这 3 种长度上进行了大量测试,因此您可能会坚持使用它们。

现在,您必须确定如何在特定情况下使用密码。加密方式的选择非常重要。加密模式是使用给定密码的一种特殊方式。最基本的是ECB(电子密码本)。它只包括使用给定密钥一个接一个地应用密码块。你应该像避免瘟疫一样避免它!

当你有加密模式时,你还没有完成。然后你必须找到我们可以称之为关键时间表的东西。也就是说,给定一个唯一密钥,例如密码或密码短语,您必须派生所需的密码密钥以提供给底层密码系统(分组密码 + 加密模式)。

我将从一个基于 AES-128(AES 与 128 位密钥一起使用)的简单模式开始。

关键时间表

从密码短语派生密钥的一个好方法是使用散列函数。您只需对密码短语和(可选)附加数据进行哈希处理即可获得实用密钥。这是我基于HMAC构造的建议:

输入: 7 到 80 个字符的密码K,指定目标用户的字符串s (如伪)和哈希函数H。

输出:一个加密密钥K s

您使用以下过程得出K s

K s = HMAC-H ( s , K )

根据H的摘要长度,您可能必须将其截断以仅获得 128 位。(众所周知的散列函数通常具有超过 128 位的输出)。例如,您可以使用H = SHA-1 或H = MD5。

密码系统

我不知道您存储的数据可以保存多长时间,但我认为它不会太大。我建议使用CBC(密码块链接)模式。这种模式需要著名的 128 位密钥和一个额外的 128 位向量,称为初始化向量(简称IV)。您绝不能使用相同的 (key, IV) 对两次!(规则1])

现在,这是你可以做的,假设:

  • 每个用户有一个数据文件
  • 您接受 IO 操作的一点开销

您将以 512 字节为基础(即 32 个 16 字节的块)对数据进行加密。IV模式很简单:您首先在 16 字节上编码 0,然后每次添加新的 512 字节块时递增它。

一个简单的例子:

用户克苏鲁想和他的朋友保持联系,分享他的邪恶阴谋。他的密码是厄运。

  • 他的数据文件将使用K Cthulhu加密,其中K = doom,因此K Cthulhu = HMAC-H (Cthulhu, doom)
  • 该文件分为 512 字节的块。数据块编号iIV是i在 16 字节上的常见整数二进制表示。

我知道 Cthulhu 可以有很多邪恶的朋友,但我可以合理地假设 16 字节整数不会溢出,因此强制执行规则 [1]。

在这里,你应该有一个基本的密码系统,它还不错,但仍然可以改进:

  • 使用带有MAC(消息验证码)方案的经过验证的加密。请注意,某些执行模式包括此,例如CCM
  • 加强密钥计划:您选择的哈希函数可能会受到彩虹表攻击。为了使攻击者的事情变得复杂,请在此过程中引入随机盐
  • 更改“每个用户一个文件”的模式,因为它仍然会泄漏一些信息,例如“嘿,您将在此处找到的内容与同一用户有关”。

第一个很容易介绍(只需使用CCM而不是CBC,您就差不多完成了)。然而,最后一点更难解决。您必须做的事情可能类似于在文件系统中所做的事情。

于 2013-04-22T11:43:20.617 回答
1

我是否必须编写相应的代码来加密和解密自己?还是有其他方法?

如前所述,hashlib 是一个标准的 python 模块,你的系统也应该带有某种加密程序。在我的系统上,它称为 openssl,您可以指定许多不同的加密算法。

#python 3
import subprocess as sp

master_key = b'hello world'
my_subprocess = sp.Popen(['openssl', 'sha1'], stdin=sp.PIPE, stdout=sp.PIPE);


my_subprocess.stdin.write(master_key)
my_subprocess.stdin.close()
print(my_subprocess.stdout.read().rstrip())
于 2013-04-23T04:57:12.547 回答