背景

我正在设计一个系统,该系统可以为静态Web内容的用户开发动态身份验证方案。动机是预先生成大量的复杂到生成,但敏感的网络包含,然后静态地将其与基于cookie的(嵌入可逆的加密信息嵌入)身份验证,由Web服务器执行。使用AEAD模式加密原始。

问题

我需要生成有效期有效的IVEC和键,例如一周(当前播种机对)。而且,过去的IVEC/键也有效说2周(历史上是valid),并且任何与历史上有效秘密加密的数据都只会与当前的valid ivec/key重新加密。

我需要的是一个确定性的csprng,它的播种是一个随机数和密码,并且可以以索引的方式64位或128位数字块产生。如果我使用数周的“ 1970年1月1日”作为我假设的CSPRNG的索引元素之一,我应该能够构建一个随着时间的流逝而自动更改键的系统。

我正在考虑的方法

现在,我在CryptoPP中没有看到这样的功能,或者现在我确实非常了解术语,并且由于CryptoPP是那里最先进的加密库,我没有信心,我会找到另一个。因此,如果我找不到那里的实现,我应该自己滚动。会从排气数据中生成静态字符串结构,然后哈希(如下所示)可以解决问题吗?

RIPEMD160(RandompRegeneratedFixedNonce:密码:UINT64SINCEEPOCH:128BITBLOCKINDEXNUMBER);

注意:将分配数字并具有常规结构,因此,对于128位消化方案,块0的前64位将用于IVEC,而元素1则用于128位键。

这是一种合理的方法(-.ie,密码范围内安全)吗?

- 编辑:发布接受评论 -

经过一定的反思,我决定将最初认为的密码/盐和nonce/盐合并为16字节(密码词强)键,并使用PKCS#5中概述的技术来衍生多个基于时间的键。不需要盐,因为没有使用密码。

有帮助吗?

解决方案

有趣的问题。

首先,您的初始向量不必是密码强的随机数量,但是它们 应该 是独特的人均。 IV实际上只是一种盐值,可确保使用相同密钥加密的类似消息不要 一旦被加密后类似。您可以使用任何快速的伪随机生成器来生成IV,然后将其与加密数据一起发送(最好是加密的)。

当然,钥匙应该尽可能强大。

在我看来,您可以放大包含nonce,密码和有效性数据的文本字符串的建议,这在我看来是非常合理的 - 它与其他系统使用密码来生成密钥的其他系统所做的事情大致相符。您应该增加多次(不只是一次)来使关键一代计算昂贵(对于试图违反钥匙的任何人来说,这将是一个更大的问题)。

您可能还想查看PKCS#5中规定的关键生成方案(例如 http://www.faqs.org/rfcs/rfc2898.html)在cryptopp中作为密码baseedekeyderivationFunction实现。该机制已经被广泛使用,已知是合理的安全性(请注意,PKCS#5建议至少将密码数据放置至少1000次)。您只需将您的有效期附加和索引数据索引到密码,并使用PasswordBaseadeKeyDerivationFunction在其上。

您没有说您建议使用什么加密算法来加密数据,但我建议您应该选择广泛使用并已知安全的东西……特别是我建议您使用AES。我还建议使用SHA Digest功能之一(也许是密码BasedBased KeyperivationFunction的输入)。 SHA-2是最新的,但是SHA-1足以用于关键生成目的。

您也不说要生成什么关键长度,但是您应该意识到,钥匙中的熵量取决于您使用的密码长度,除非密码是 非常 长期将比理想的键长要少得多。

该方案中最薄弱的链接是密码本身,这总是会限制您可以实现的安全级别。只要您加盐(就像您正在这样做一样),并使关键产生昂贵,以减慢蛮力攻击,就可以了。

其他提示

我需要的是一个确定性的csprng,它的播种是一个随机数和密码,并且可以以索引的方式64位或128位数字块产生。如果我使用数周的“ 1970年1月1日”作为我假设的CSPRNG的索引元素之一,我应该能够构建一个随着时间的流逝而自动更改键的系统。

好吧,我 思考 解决方案的一部分是使用非时代的生成器。这样,如果双方都以相同的种子开头,那么它们都会产生相同的随机流。您可以将“自1970年第1周以来的几周”分层。

为此,您将使用 OFB_mode<T>::Encryption. 。它可以用作发电机,因为OFB模式使用 AdditiveCipherTemplate<T>, ,源自 RandomNumberGenerator.

实际上,crpyto ++在 test.cpp 因此,如果某事失败,则可以再现结果。这是您的使用方式 OFB_mode<T>::Encryption. 。它也适用于 CTR_Mode<T>::Encryption:

SecByteBlock seed(32 + 16);
OS_GenerateRandomBlock(false, seed, seed.size());

for(unsigned int i = 0; i < 10; i++)
{
    OFB_Mode<AES>::Encryption prng;
    prng.SetKeyWithIV(seed, 32, seed + 32, 16);

    SecByteBlock t(16);
    prng.GenerateBlock(t, t.size());

    string s;
    HexEncoder hex(new StringSink(s));

    hex.Put(t, t.size());
    hex.MessageEnd();

    cout << "Random: " << s << endl;
}

打电话 OS_GenerateRandomBlock/dev/{u|s}random 然后将其用作模拟的共享种子。程序的每次运行都会有所不同。在程序的每次运行中,它的打印类似于以下内容:

$ ./cryptopp-test.exe
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD

还有另一个可用的发电机,但它不是加密++库的一部分。它叫 AES_RNG, ,及其基于AES-256。它仅是标题的实现,您可以在Crypto ++ Wiki下找到它 Randomnumbergenerator.

另请参阅主题 可重复性 为了 RandomNumberGenerator 加密++ Wiki上的课。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top