对 CBC 和 ECB 使用相同的 AES 密钥
概述
我试图想出一种方法,让服务器和客户端能够为每个请求生成唯一的 IV,该 IV 对于每个客户端来说都是不同的,但具有确定性。我所说的确定性是指服务器只需知道起始序列就可以计算未来任何请求的 IV。
我需要此功能的原因是我正在使用 AES 加密来实现一次性密码 (OTP) 方案。当客户端登录到服务器时,它会获得一个种子。第一个 OTP 是通过加密该种子生成的。对于每个后续请求,客户端使用服务器和客户端之间的共享 AES 密钥加密最后一个 OTP。因此,即使攻击者在没有共享密钥的情况下嗅探到最后一个 OTP,他们也无法获得下一个 OTP。 OTP 正在 CBC 模式下使用 AES 进行加密。如果服务器和客户端不同步,就会出现问题。我计划处理这个问题的方法是在服务器端生成一些将来的 OTP,并查看其中是否有与客户端匹配的 OTP。然而,如果没有办法确定性地计算每次加密迭代的 IV,这是不可能的。
在讨论我提出的解决方案之前,让我先表达一下我对 AES、IV、CBC 和 ECB 的理解。这样,如果我对基础知识有任何误解,都可以指出并纠正。
理论
ECB
我知道 ECB 将为使用相同密钥加密的相同明文块产生相同的输出。因此,它不应该用于多个数据块,因为可以通过统计分析数据来辨别有关明文的信息。基于此,如果您能保证您的数据始终小于 16 字节(128 位),那么似乎可以消除统计攻击的问题。此外,如果您还可以保证您从未使用相同的密钥加密相同的明文,那么您将永远不会得到相同的输出。因此,在我看来,假设您的系统始终满足这些非常严格的标准,那么使用 ECB 是安全的。
CBC 和 IV
我知道 CBC 旨在消除这两个问题。通过链接区块,消除了 ECB 的多区块统计攻击。通过不对相同的 AES 密钥使用相同的 IV,您可以消除使用相同的密钥将相同的明文加密到相同输出的问题。
密钥唯一性
如果每个客户端都获得生成的 AES 密钥,那么虽然多个用户拥有相同密钥的可能性很小,但这种可能性非常小。因此,可以安全地假设没有两个客户端将使用相同的 AES 密钥。
建议的解决方案
我建议的解决方案是为每个客户端提供唯一的 AES 密钥。当生成密钥时,计数器将被初始化为随机数。每次必须加密某些内容时,计数器都会加一。该数字将被填充到一个块中,然后在 ECB 模式下使用 AES 进行加密。其输出将是我使用 CBC 加密数据的 IV。
如果服务器与客户端的计数器不同步,因为它具有相同的密钥并且 ECB 不需要 IV,它可以继续生成 IV,直到找到允许数据解密的 IV。
我的想法是这个 IV 不会受到统计攻击,因为它等于 AES 的块大小。此外,每个用户每次都会有所不同,因为每个用户都有一个唯一的密钥,并且计数器将始终递增。显然,AES 密钥必须安全传输(现在客户端正在使用服务器的 RSA 公钥加密生成的密钥)。
我的问题
我对提议的解决方案中描述的技术的基本理解正确吗?我提出的解决方案有什么明显的错误吗?使用相同的密钥以建议的方式生成 IV 以及使用 CBC 加密是否存在任何安全缺陷?
我意识到最后一个问题可能很难/不可能回答,因为密码学真的很难,但任何见解都会受到赞赏。
提前致谢。
Overview
I'm trying to come up with a way for a server and client to be able to generate a unique IV for each request that is both different for every client and yet deterministic. What I mean by deterministic is that the server can calculate the IV for any request in the future knowing only the starting sequence.
The reason I am need this capability is that I'm using the AES encryption to implement a one time password (OTP) scheme. When the client logs into the server it is given a seed. The first OTP is generated by encrypting this seed. For each subsequent request the client encrypts the last OTP using the shared AES key between the server and the client. Hence, even if an attacker sniffed the last OTP without the shared key they would not be able to get the next OTP. The OTP is being encrypted with AES in CBC mode. The problem comes if the server and client get out of sync. The way I was planning on dealing with this was by generating a few OTP's into the future on the server side and seeing if any of them matched the client's. However, without a way to deterministically calculate the IV for each encryption iteration this is not possible.
Before I get into my proposed solution let me express my understanding about AES, IV's, CBC, and ECB. That way if I have any misunderstandings in my fundamentals they can be pointed out and corrected.
Theory
ECB
I know that ECB will produce the same output for identical blocks of plaintext encrypted with the same keys. Hence it shouldn't be used for multiple blocks of data because information about the plaintext can be discerned by statistically analyzing the data. Based on this it would seem that if you could guarantee your data was always less than 16 bytes (128 bits) it would eliminate the problem of the statistical attack. In addition if you could also guarantee that you never encrypted the same plaintext with the same key you would never get the same output. Therefore it seems to me that using ECB is safe assuming your system will always meet these very strict criteria.
CBC and IV
I know that CBC is meant to eliminate both of these problems. By chaining blocks it eliminates the multi block statistical attack of ECB. By never using the same IV for the same AES key you eliminate the problem of having the same plaintext encrypt to the same output with the same key.
Key Uniqueness
If each client gets a generated AES key then while there is a small probability of multiple users having the same key the chances are extremely small. Therefore it is safe to assume that no two clients will be using the same AES key.
The Proposed Solution
My proposed solution is to give each client a unique AES key. When the key is generated a counter will be initialized to a random number. Each time something must be encrypted the counter will increment by one. This number will be padded to a block and then encrypted using AES in ECB mode. The output of this will be my IV for encrypting the data using CBC.
If the server gets out of sync with the client's counter because it has the same key and ECB requires no IV it can keep generating IV's until it finds one that allows the data to be decrypted.
My thoughts are this IV is safe from the statistical attack because it is equal to the block size of AES. In addition it will be different for every user, every time because each user will have a unique key and the counter will always increment. Obviously the AES keys must be transmitted securely (right now the client is encrypting the generated key with the server's public RSA key).
My Questions
Is my fundamental understanding of the technologies described in the proposed solution correct? Is there anything obviously wrong with my proposed solution? Is there any security flaw of using the same key to generate the IV in the proposed manner as well as to encrypt using CBC?
I realize the last question may be difficult/impossible to answer because cryptography is really hard, but any insight would be appreciated.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如评论中所述,我会不惜一切代价避免发明协议,而是尝试实现标准化协议。某些 OTP 协议要求客户端在登录服务器时使用第二个带外设备来接收 OTP,银行的常见情况是,在您向服务器应用程序发出登录请求时,服务器会将 OTP 发送到你的手机。客户端和服务器的 OTP 生成器通常是时间同步或反同步的,如果我理解正确的话,您计划使用后一种解决方案。我在您的描述中没有找到您打算如何在单独的设备上管理客户的柜台?
无论如何,我建议使用已经“现场测试”的标准化程序,而不是推出我自己的方案。 HOTP 可能就是您正在寻找的 - 尽管它使用密钥 HMAC 解决方案而不是对称加密,但这应该会让事情变得更容易,因为你不必再担心 IV。
无论如何,您应该尽早计划如何与客户建立对称密钥。如果您无法通过安全通道处理此问题(例如亲自分发密钥),这将成为整个系统的安全问题。
As stated in the comments, I would avoid to invent a protocol at all cost and rather try to implement a standardized protocol. Some OTP protocols require the clients to use a second, out-of-band device for receiving the OTP when logging into a server, a common scenario with banks is that upon your login request to the server application the server will send you an OTP to your cellphone. The OTP generators for client and server are typically time-synchronized or counter-synchronized, if I understood correctly you plan to use the latter solution. I didn't find in your description how you would intend to manage the client's counter, on a separate device?
Anyway, I would recommend to use a standardized procedure that has been "tested in the field" rather than rolling my own scheme. HOTP could be what you are looking for - although it uses a keyed HMAC solution rather than symmetric encryption, but this should make things easier as you don't have to worry about the IV anymore.
In any case you should plan early on how you want to accomplish establishing the symmetric keys with your clients. If you can't handle this over a secure channel (such as handing out keys in person) this will become a problem for the security of the entire system.
好吧,只是一个想法...如果你想要一些自同步的东西,你可以将 AES 设置为密码反馈模式...这样你的密文将被用作 IV ...如果双方不同步,一个密文块足以重新获得同步(但是将带来重新同步的同步将无法解密,因为前一个不可用)
well just a thought ... if you want something self synchronizing, you could set AES up in cipher feedback mode ... that way your cipher text will be used as IV ... if both sides get out of sync, one ciphertext block is enough to regain sync (but the one that will bring re-sync won't be decryptable since the previous one is not available)
你甚至可以去掉 ECB 部分,原则上 IV 的一个真正的特点是它应该是唯一的,而计数器很可能是唯一的。由于在攻击期间使计数器保持唯一性很困难(例如参见 WEP 加密),因此最好使用安全随机数(真正的安全随机数,而不是“Sony PS3”安全随机数或 XKCD 安全随机数)。
您对加密的理解似乎不错,但我仍然会接受其他建议,并且仅在其他所有方法都失败时才采用您自己的方案(和实现)。
You can even do away with the ECB part, in principle the one real thing about an IV is that it should be unique, and a counter could very well be. Since it is tricky to get the counter to be unique during attacks (see e.g. WEP encryption), it's much better to use a secure random (a real secure random, not a "Sony PS3" secure random or XKCD secure random).
Your understanding of crypto seems OK, but I would still go with the other recommendations and only go for your own schemes (and implementations) if all else fails.