我正在编写一个安全性基于PolarSSL包提供的crypt_and_hash example的应用程序。在该示例中,crypt_and_hash接收密钥(通过命令行参数提供)和随机的16字节IV。然后将它们混合在一起8192次(原因我不知道,但除了问题之外):
memset( digest, 0, 32 );
memcpy( digest, IV, 16 );
for( i = 0; i < 8192; i++ )
{
md_starts( &md_ctx );
md_update( &md_ctx, digest, 32 );
md_update( &md_ctx, key, keylen );
md_finish( &md_ctx, digest );
}
然后,它接受输出和使用是通过cipher_setkey在密码上下文中设置密钥,后来用于执行所有加密/解密操作:
if( cipher_setkey( &cipher_ctx, digest, cipher_info->key_length,
POLARSSL_ENCRYPT ) != 0 )
我注意到,当crypt_and_hash创建其摘要时,它在其缓冲区中仅设置20个字节,后跟12个空字节,无论加密方案和提供的密钥大小如何。我尝试了不同的方案和密钥大小来测试它。密钥大小不应该根据加密(例如AES-256为32字节,AES-128为16字节)?为什么总是20?
答案 0 :(得分:1)
这里有一个专有的基于密码的密钥派生函数(PBKDF)。此功能似乎允许键加强或键拉伸,但不允许键扩展。
如果此密钥不是完全随机的,则可以使用密钥强化来强制强制键值(或密码值)。它由循环使用IV(实际上是 salt )和密码散列函数中的密钥实现。如果你收到20个字节,这可能是SHA-1,因为它有160位输出。
算法未提供密钥扩展。密钥扩展是您正在考虑的:将计算的随机数分布在X个位上。它相对容易实现;可能最好的办法是看看HKDF的关键扩展算法。
目前,该方案受到PBKDF内散列输出的限制。当然,如果您使用SHA-256,那么一个 AES-256密钥就足够了。或者,如果为每次加密使用不同的盐,则可以使用SH-384导出AES-256密钥,并将剩余的位用作IV(用于加密)。
请注意术语key stretching is not always used to mean the same thing。
答案 1 :(得分:0)
crypt_and_hash 是PolarSSL提供的示例,用于说明如何同时使用密码和md图层。如果使用SHA-1,它只能从MD获得最多20个字节(160位),从而进入要使用的密钥..
如果要使用需要更大密钥的密码(例如AES-256),则需要在命令行上使用不同的哈希算法,例如SHA-256或SHA-512,这将填满整个32字节的密钥空间..