简体   繁体   English

使用非对称加密来保护密码

[英]Using asymmetric encryption to secure passwords

Due to our customer's demands, user passwords must be kept in some "readable" form in order to allow accounts to be converted at a later date. 根据客户的需求,必须以某种“可读”的形式保存用户密码,以便以后可以转换帐户。 Unfortunately, just saving hash values and comparing them on authentication is not an option here. 不幸的是,仅保存哈希值并在身份验证中进行比较不是这里的选择。 Storing plain passwords in the database is not an option either of course, but using an encryption scheme like AES might be one. 当然,在数据库中存储普通密码也不是一种选择,但是使用诸如AES之类的加密方案可能是一种选择。 But in that case, the key to decrypt passwords would have to be stored on the system handling authentication and I'm not quite comfortable with that. 但是在那种情况下,解密密码的密钥必须存储在处理身份验证的系统上,我对此不太满意。

Hoping to get "best of both worlds", my implementation is now using RSA asymmetric encryption to secure the passwords. 为了实现“两全其美”,我的实现现在使用RSA非对称加密来保护密码。 Passwords are salted and encrypted using the public key. 使用公共密钥对密码进行加密和加密。 I disabled any additional, internal salting or padding mechanisms. 我禁用了任何其他内部加盐或填充机制。 The encrypted password will be the same every time, just like a MD5 or SHA1 hashed password would be. 每次都使用相同的加密密码,就像MD5或SHA1哈希密码一样。 This way, the authentication system needs the public key, only. 这样,身份验证系统仅需要公共密钥。 The private key is not required. 不需要私钥。

The private key is printed out, sealed and stored offline in the company's safe right after it is created. 私钥创建后立即打印出来,密封并离线保存在公司的保险箱中。 But when the accounts need to be converted later, it will allow access to the passwords. 但是,当以后需要转换帐户时,它将允许访问密码。

Before we deploy this solution, I'd like to hear your opinion on this scheme. 在我们部署此解决方案之前,我想听听您对这个方案的看法。 Any flaws in design? 设计有任何缺陷吗? Any serious drawbacks compared to the symmetric encryption? 与对称加密相比有什么严重的缺点吗? Anything else we are missing? 我们还缺少什么?

Thank you very much in advance! 提前非常感谢您!

-- -

Update: In response to Jack's arguments below, I'd like to add the relevant implementation details for our RSA-based "hashing" function: 更新:针对下面Jack的论点,我想为基于RSA的“哈希”函数添加相关的实现细节:

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher rsa = Cipher.getInstance("RSA/None/NoPadding");
rsa.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cryptRaw = rsa.doFinal(saltedPassword.getBytes());

Having quickly skimmed over the paper mentioned by Jack, I think I somewhat understand the importance of preprocessing such as OAEP. 在快速浏览了Jack提到的论文之后,我想我有点理解了诸如OAEP之类的预处理的重要性。 Would it be alright to extend my original question and ask if there is a way to apply the needed preprocessing and still have the function return the same output every time for each input, just as a regular hashing function would? 是否可以扩展我的原始问题,并询问是否有一种方法可以应用所需的预处理,并且仍然让函数每次为每个输入返回相同的输出,就像常规的哈希函数一样? I would accept an answer to that "bonus question" here. 在这里,我将接受对“奖金问题”的回答。 (Or should I make that a seperate question on SOF?) (或者我应该对SOF提出一个单独的问题吗?)

-- -

Update 2: I'm having a hard time accepting one of the present answers because I feel that none really does answer my question. 更新2:我很难接受当前的答案之一,因为我觉得没有人能真正回答我的问题。 But I no longer expect any more answers to come, so I'll accept the one that I feel is most constructive. 但是我不再期望会有更多的答案,因此,我将接受我认为最有建设性的答案。

I'm adding this as another answer because instead of answering the question asked (as I did in the first response) this is a workaround / alternative suggestion. 我将其添加为另一个答案,因为这是一种变通方法/替代建议,而不是像我在第一个响应中那样回答所提出的问题。

Simply put: 简单的说:

Use hashes BUT, whenever a user changes their password, also use your public key as follows: 每当用户更改密码时,都使用哈希哈希表,但也可以使用您的公共密钥,如下所示:

  • Generate a random symmetric key and use it to encrypt the timestamp, user identifier, and new password. 生成一个随机对称密钥,并使用它来加密时间戳,用户标识符和新密码。
    • The timestamp is to ensure you don't mess up later when trying to find the current / most up-to-date password. 时间戳是为了确保以后尝试查找当前/最新密码时不会混乱。
    • Username so that you know which account you're dealing with. 用户名,以便您知道要使用哪个帐户。
    • Password because it is a requirement. 密码,因为这是必需的。
  • Store the encrypted text. 存储加密的文本。
  • Encrypt the symmetric key using your public key. 使用您的公共密钥加密对称密钥。
  • Store the public key encrypted symmetric key with the encrypted text. 将公共密钥加密的对称密钥与加密的文本一起存储。
  • Destroy the in-memory plaintext symmetric key, leaving only the public key encrypted key. 销毁内存中的纯文本对称密钥,仅保留公钥加密密钥。

When you need to 'convert' the accounts using the current password, you use the private key and go through the password change records. 当您需要使用当前密码“转换”帐户时,可以使用私钥并浏览密码更改记录。 For each one: 每一个人:

  • Using the private key, decrypt the symmetric key. 使用私钥解密对称密钥。
  • Using the symmetric key, decrypt the record. 使用对称密钥,解密记录。
  • If you have a record for this user already, compare timestamps, and keep the password that is most recent (discarding the older). 如果您已经有该用户的记录,请比较时间戳记,并保留最新的密码(丢弃较旧的密码)。
  • Lather, rinse, repeat. 泡沫,冲洗,重复。

(Frankly I'm probably overdoing things by encrypting the timestamp and not leaving it plaintext, but I'm paranoid and I have a thing for timestamps. Don't get me started.) (坦率地说,我可能是通过加密时间戳而不是保留明文的方式来做事,但是我很偏执,并且对时间戳有些担心。不要让我开始。)

Since you only use the public key when changing passwords, speed isn't critical. 由于仅在更改密码时使用公共密钥,因此速度并不重要。 Also, you don't have to keep the records / files / data where the plaintext password is encrypted on the server the user uses for authentication. 同样,您也不必将记录/文件/数据保存在用户用于身份验证的服务器上的明文密码已加密的位置。 This data can be archived or otherwise moved off regularly, as they aren't required for normal operations (that's what the hash is for). 该数据可以被存档或以其他方式定期移出,因为常规操作不需要它们(这就是哈希的用途)。

There is not enough information in the question to give any reasonable answer. 问题中没有足够的信息来给出任何合理的答案。 Anyway since you disable padding there is a good chance that one of the attacks described in the paper "Why Textbook ElGamal and RSA Encryption are Insecure" by D. Boneh, A. Joux, and P. Nguyen is applicable. 无论如何,由于禁用了填充,所以很有可能适用D. Boneh,A。Joux和P. Nguyen在论文“为什么教科书ElGamal和RSA加密不安全”中描述的一种攻击。

That is just a wild guess of course. 当然,这只是一个疯狂的猜测。 Your proposal could be susceptible to a number of other attacks. 您的提案可能会受到其他多种攻击。

In terms of answering your specific question, my main concern would have been management of the private key but given it's well and truly not accessible via any computer system breach, you're pretty well covered on that front. 在回答您的特定问题方面,我主要关心的是私钥的管理,但是鉴于它确实可以通过任何计算机系统违规访问,因此在这方面已经相当不错。

I'd still question the logic of not using hashes though - this sounds like a classic YAGNI . 我仍然会质疑不使用哈希的逻辑-听起来像是经典的YAGNI A hashing process is deterministic so even if you decided to migrate systems in the future, so long as you can still use the same algorithm, you'll get the same result. 哈希过程是确定性的,因此即使您将来决定迁移系统,只要您仍然可以使用相同的算法,就可以获得相同的结果。 Personally, I'd pick a strong hash algorithm, use a cryptographically strong, unique salt on each account and be done with it. 就我个人而言,我会选择一个强大的哈希算法,在每个帐户上使用具有加密功能的独特盐,然后使用它。

It seems safe enough in terms of what is online but have you given full consideration to the offline storage. 就联机内容而言,这似乎已经足够安全,但是您是否已充分考虑了脱机存储。 How easy will it be for people within your company to get access to the private key? 公司内部人员访问私钥有多容易? How would you know if someone within your company had accessed the private key? 您如何知道公司内部是否有人访问了私钥? How easy would it be for the private key to be destroyed (eg is the safe fireproof/waterproof, will the printed key become illegible over time etc). 私钥被销毁的难易程度(例如安全的防火/防水功能,随着时间的推移,印刷的密钥将变得难以辨认等)。

You need to look at things such as split knowledge, dual control, tamper evident envelopes etc. As a minimum I think you need to print out two strings of data which when or'd together create the private key and then have one in your office and one in your customers office, 您需要查看诸如拆分知识,双重控制,篡改明显信封之类的内容。至少,我认为您需要打印出两个数据串,这些数据串在一起或共同创建私钥时,然后在您的办公室中放一个还有一个在您的客户办公室,

One serious drawback I've not seen mentioned is the speed. 我没有提到的一个严重缺点是速度。

Symmetric encryption is generally much much faster than asymmetric. 对称加密通常比非对称要快得多。 That's normally fine because most people account for that in their designs (SSL, for example, only uses asymmetric encryption to share the symmetric key and checking certificates). 通常这很好,因为大多数人在设计中都考虑到了这一点(例如,SSL仅使用非对称加密来共享对称密钥和检查证书)。 You're going to be doing asymmetric (slow) for every login, instead of cryptographic hashing (quite fast) or symmetric encryption (pretty snappy). 您将对每次登录执行不对称(缓慢)操作,而不是使用加密哈希(非常快)或对称加密(非常灵活)。 I don't know that it will impact performance, but it could. 我不知道这会影响性能,但是会影响性能。

As a point of comparison: on my machine an AES symmetric stream cipher encryption (aes-128 cbc) yields up to 188255kB/s. 作为比较点:在我的机器上,AES对称流密码加密(aes-128 cbc)产生高达188255kB / s。 That's a lot of passwords. 那是很多密码。 On the same machine, the peak performance for signatures per second (probably the closest approximation to your intended operation) using DSA with a 512 bit key (no longer used to sign SSL keys) is 8916.2 operations per second. 在同一台计算机上,使用具有512位密钥(不再用于对SSL密钥进行签名)的DSA的每秒签名的峰值性能(可能是最接近您的预期操作)为每秒8916.2次操作。 That difference is (roughly) a factor of a thousand assuming the signatures were using MD5 sized checksums. 假设签名使用的是MD5大小的校验和,则该差异(大约)是千分之一。 Three orders of magnitude. 三个数量级。

This direct comparison is probably not applicable directly to your situation, but my intention was to give you an idea of the comparative algorithmic complexity. 这种直接比较可能并不直接适用于您的情况,但是我的目的是让您了解比较算法的复杂性。

If you have cryptographic algorithms you would prefer to use or compare and you'd like to benchmark them on your system, I suggest the 'openssl speed' command for systems that have openssl builds. 如果您有加密算法,则希望使用或比较它们,并希望在系统上对其进行基准测试,对于具有openssl构建的系统,我建议使用“ openssl speed”命令。

You can also probably mitigate this concern with dedicated hardware designed to accelerate public key cryptographic operations. 您也可以使用专用于加速公钥加密操作的专用硬件来减轻这种担忧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM