3

我处于一个棘手的情况,我正在编写一个使用我公司的电子邮件帐户向客户发送电子邮件的应用程序。这里的问题是我必须拥有该帐户的密码才能使服务器上的邮件服务从该帐户发送电子邮件。我知道密码永远不应该以纯文本形式存储,尤其是用于重要电子邮件帐户的密码。这里的困境是程序需要有实际的纯文本密码才能发送电子邮件,所以它需要存储在程序可以访问的某个地方。该程序使用 MySQL 数据库来存储信息,所以我想到了三个选项:

1) 将密码存储在程序的内存中,即私有的最终字符串字段。

2)服务器上可以读取密码的文件

3) MySQL 数据库中的某处。

我认为 1 是最安全的选择,但有没有人有想法来处理这种情况,以尽量减少密码落入坏人之手的风险?谢谢你的建议!

4

3 回答 3

4

指出 SMTP 不需要身份验证的评论是正确的。也就是说,假设服务器使用商用硬件和软件,您指定的所有三个选项都是不安全的。我会说明为什么每个都是不安全的,尽管我不会遵循你原来的顺序。

2)服务器上可以读取密码的文件

3) MySQL 数据库中的某处。

如果有人要窃取服务器怎么办?然后,他们只需打开文件或数据库,读取密码,就可以立即访问公司的所有重要信息。因此,除非您日夜在服务器周围有武装警卫,否则这已经很不安全了。

但它变得更糟。没有计算机系统是完全无懈可击的,过去几年多次广为人知的攻击(例如索尼的 PlayStation Network)表明,攻击者无需物理访问即可获取磁盘文件和数据库的内容。此外,从您的问题来看,有问题的服务器似乎是为了接受来自外部世界的数据包(HTTP 请求、传入的电子邮件等),这增加了您的攻击面。

1) 将密码存储在程序的内存中,即私有的最终字符串字段。

这很诱人,但这比选项 2 或选项 3 更有害。一方面,私有最终字符串字段存储在 Java 编译器生成的 .class 文件中,因此使用此选项您已经存储了未加密的密码在服务器的硬盘上。在如选项 2 或 3 中破坏服务器后,攻击者可以运行javap以从 .class 文件中获取明文密码。

但是,这种方法进一步扩大了您的攻击面。如果密码作为源代码的一部分存储,那么所有正在处理代码的开发人员都可以使用它。在最小权限原则下,开发者不应该知道额外的密码,这里有一个很好的理由。如果任何开发人员的机器被盗或从外部入侵,攻击者可以查看被入侵机器的硬盘并获取明文密码。然后是源代码控制。源代码控制真正重要的好处之一是它允许您检查代码的任何先前版本。因此,即使您将来切换到安全方法,如果密码曾经进入源代码控制,那么源代码控制服务器就是一个潜在的攻击点。

所有这些因素加起来表明,即使 HTTP/邮件服务器的安全性是一流的,选项 1 也会大大增加攻击面,以至于 HTTP/邮件服务器的安全性并没有真正的帮助。


额外细节:一开始我指定“假设服务器使用商品硬件和软件”。如果您不使用商品硬件和软件,您可以执行诸如从只读存储启动并仅使用加密数据库之类的操作,这需要一个人在每次启动时提供解密密钥。之后,解密的信息只存在于内存中,永远不会写入磁盘。这样,如果服务器被盗,攻击者必须拔下服务器,从而丢失所有仅在内存中的解密信息。这种设置有时用于 Kerberos KDC(将服务器放在一个上锁的盒子中以提高安全性),但很少使用其他设置,坦率地说,如果有一种简单的方法可以解决您的问题而无需额外花费费用。

于 2012-04-13T00:28:33.653 回答
1

如果您认真对待它的安全,您可以对密码进行编码并将其放入 2 或 3 中。当您需要使用它时,只需让您的程序对其进行解码并将其作为纯字符串保存在内存中。

前任。

String encodedUrl = URLEncoder.encode(url,"UTF-8"); 

String decodedUrl = URLDecoder.decode(url,"UTF-8");

于 2012-04-12T21:42:01.903 回答
1

这是一个常见的问题。您可以将密码存储在 MYSQL 中的 blob 字段中,在插入时应用 AES 加密;在 java 中使用和保存 key_string 以便于解密。

MYSQL 语法:

AES_ENCRYPT(str,key_str)

AES_DECRYPT(crypt_str,key_str)

插入将类似于以下内容:

INSERT INTO t VALUES (1,AES_ENCRYPT('password','encryption_key'));

您将使用密钥解密出来

SELECT AES_DECRYPT(password, 'encryption_key') AS unencrypted FROM t

因此,尽管您需要加密密钥,但您永远不会将密码作为纯文本存储在应用程序中。您与数据库的连接应该是安全的。日志可能是个问题。

或者,您可以使用存储的过程来获取和输出密钥,或者您可以在服务器端加密它们并在加密后插入/检索。

于 2012-04-12T23:51:34.310 回答