基于PBKDF的AES密钥的强度

时间:2014-01-10 00:18:51

标签: c security encryption cryptography openssl

这是一个系统的存根,它将在OpenSSL中使用AES 256 CBC生成密钥对。下面代码的目的是生成两个随机密钥,一个AES密钥和一些其他公共数据。 AES密钥将用于交换共享机密。

免责声明:我不是密码学或安全系统方面的专家。我确实意识到了危险,但这项工作的重点是学术兴趣。如果有新手错误或完全且危险的错误,请指出它以帮助我学习。

// The key_generator() will produce the following public keys in addition
// to a couple of other private keys.
// public_identifier
// public_salt
// public_composite_identifier
// public_aes_key

int key_generator(/*some args*/)
{
    // Step 1
    //Obtain public_identifier. Possibly a hashed value of an unique ASCII string.
    unsigned char *public_identifier;


    // Step 2
    //Generate 256 bit private_primary_random_passkey which is secret. 
    //This random key is generated once and reused later.
    unsigned char *private_primary_random_passkey;

    if(RAND_bytes(private_primary_random_passkey, 256) == 0)     
        return FAILURE;


    // Step 3
    //Generate private_composite_identifier using public_identifier
    //and private_primary_random_passkey.
    //IMPORTANT - The method to obtain private_composite_identifier 
    //may be publicly known.  
    //The public_identifier is also publicly known but the 
    //private_primary_random_passkey is secret.
    unsigned char *private_composite_identifier;

    //<Some code for generating private_composite_identifier>
    //.....
    //</code>


    // Step 4     
    //Generate temporary temp_private_aes_key and temp_private_aes_IV;
    //NOTE - Used dummy vars wherever key length is required. 
    //Assume correct length is passed in.

    int aes_rounds = 25000;

    unsigned char *temp_private_aes_key;
    unsigned char *temp_private_aes_IV;

    if(EVP_BytesToKey(EVP_aes_256_cbc(), 
                      EVP_sha512(), 
                      private_composite_identifier, 
                      private_primary_random_passkey, 
                      private_composite_identifier_length/8, 
                      aes_rounds, 
                      temp_private_aes_key, 
                      temp_private_aes_IV) == 0)     
        return FAILURE;    


    // Step 5
    //Generate 128 bit random salt which is public.
    unsigned char *public_salt;

    if(RAND_bytes(public_salt, 128) == 0)     
        return FAILURE;


    // Step 6
    //Generate private_composite_identifier and public_composite_identifier 
    //using temp_private_aes_key and public_salt.
    unsigned char *public_composite_identifier;
    unsigned char *private_composite_identifier;

    if(EVP_BytesToKey(EVP_aes_256_cbc(), 
                      EVP_sha512(), 
                      temp_private_aes_key,
                      public_salt,
                      temp_private_aes_key_length/8, 
                      aes_rounds, 
                      private_composite_identifier, 
                      public_composite_identifier) == 0)     
        return FAILURE;    


    // Step 7
    //Generate 128 bit private_secondary_random_passkey which is secret. 
    //This random key is generated once and reused later.
    unsigned char *private_secondary_random_passkey;

    if(RAND_bytes(private_secondary_random_passkey, 128) == 0)     
        return FAILURE;

    unsigned char *private_aes_key;
    unsigned char *public_aes_key;

    if(EVP_BytesToKey(EVP_aes_256_cbc(), 
                      EVP_sha512(), 
                      private_composite_identifier,
                      private_secondary_random_passkey,
                      private_composite_identifier_length/8, 
                      aes_rounds, 
                      private_aes_key, 
                     public_aes_key) == 0)     
        return FAILURE
}

以下是我的问题:

  • 是否应使用RSA密钥对而不是AES密钥?为什么一个人比另一个更受欢迎?
  • 由于用于生成密钥对的密钥很长,随机生成和加盐,以后使用相同的AES / RSA密钥对是否安全?我了解彩虹表和其他措施的风险,但是随后的盐和密钥随后是三级密钥生成而不是那些担忧减轻了吗?
  • 恶意攻击者使用公开数据重建密钥对或破坏此系统的方式有哪些?
  • 您可以考虑阻止或增强此系统的任何其他要点。

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

你真的进入了密码学工程,Crypto Stack Exchange上的人可能更适合这些设计问题。

此外,您缺少任何有用的回复的详细信息。 (当问题更具实施性和具体性时,请回来。)


  

基于PBKDF的AES密钥的强度

首先是标题。

这个问题与猜测密码一样困难,并且可能更容易使用过去数据泄露的数百万字词列表。也就是说,攻击者不会试图破解AES密钥 - 他或她将尝试猜测您用来获取密钥的密码。

要键入具有128位安全性的AES-128密钥,密码中需要128位熵。密码不是随机的,英文每个字母有大约1.3位的熵,所以期望使用大约14个字符的密码用于AES-128。如果要键入AES-256,请使用28+字符的密码。


  

以下代码的目标是生成两个随机密钥,一个AES密钥和一些其他公共数据。 AES密钥将用于交换共享密钥。

这里的目标是什么?要创建安全通道?或者只是换钥匙?

通常,您使用公钥来传输或协议传输对称密钥或会话密钥。即:(1)使用Diffie-Hellman生成共享密钥(&#39;密钥协议&#39;因为双方都添加到进程中),然后在共享秘密下传输对称会话密钥;或(2)使用RSA运输主人&#39;对称会话密钥(&#39;密钥传输&#39;因为一方生成秘密,在对等方的RSA密钥下对其进行加密,然后将其发送给对等方。)

有基于共享机密和密码的经过身份验证的密钥交换。 SSL / TLS有两个 - 预共享密钥(PSK)和安全远程密码(SRP)。 PSK使用AES作为基元,SRP使用Diffie-Hellman。

PSK和SRP通常比DH和RSA更好,因为它们提供(1)相互认证和(2)通道绑定。根据您的陈述&#34; AES密钥将用于交换共享秘密&#34;,PSK可能是您的最佳选择。但是,如果它们是一个不错的选择则不明显,因为我们不知道你想要完成什么。


  

是否应使用RSA密钥对而不是AES密钥?为什么一个人比另一个更受欢迎?

这取决于您的问题域以及您要执行的操作。

如果服务器有公共RSA密钥,那么您将使用Diffie-Hellman或RSA。如果您和服务器共享一个秘密,那么请避免使用公钥密钥并使用PSK或SRP。

Diffie-Hellman和RSA在计算方面很昂贵。它们通常用于交换或传输对称密钥。 RSA-2048可能需要4到5百万条指令,这会削弱性能。

对称密码在计算方面很快。它们一次用于大部分流量 Diffie-Hellman或RSA已完成。我们称之为批量加密,它们是脂肪。如果你有Ivy Bridge硬件,那么AES-NI可以接收1个周期/字节的加密数据。

当您阅读像nginx这样的Web服务器只能处理1000个SSL / TLS连接时,您会看到Diffie-Hellman和RSA的影响。一旦这些频道被设置并加密以进行批量加密,它就可以处理数千个加密的流量流。

  

以后使用相同的AES / RSA密钥对是否安全?

这些是苹果和橘子。您通常长期使用RSA密钥对,而AES密钥仅限于会话。

通常,协议的每次运行都应使用不同的参数。该协议还应该缺少对称性,以便攻击者无法启动协议的第二个实例,然后让服务器回答第一个实例上出现的第二个实例的问题。


  

我理解彩虹表和其他措施的风险,但是这些问题并没有随机盐和键随后三级密钥生成而减轻?

这取决于您的问题域以及您要执行的操作。我们无法回答,因为我们不知道您要完成的任务。

请参阅OWASP的John Steven的Password Storage Cheat Sheet。他带您了解威胁模型并解释系统的各个部分。详细的治疗方法可在Secure Password Storage获得。


  

恶意攻击者使用公开数据重建密钥对或破坏此系统的方式有哪些?

这取决于您的问题域以及您要执行的操作。我们无法回答,因为我们不知道您要完成的任务。

密钥管理是密码学中最难的部分,我们所看到的只是一个真空:

int key_generator(/*some args*/)

您需要详细说明所有参数,管理方式以及使用方法。


  

您可以考虑阻止或增强此系统的任何其他要点。

跳出来:三次拨打RAND_byesEVP_BytesToKey。通常,您这样做:

byte[] master = Random(16) // or 32, or however many you need
byte[] key1 = Derive(master, "<some usage>", <other distinguishing information>)
byte[] key2 = Derive(master, "<some usage>", <other distinguishing information>)
byte[] key3 = Derive(master, "<some usage>", <other distinguishing information>)

master可能来自密钥交换或密钥协议。

key1key2key3会有所不同,因为(1)调用之间的使用情况不同,以及(2)其他区分信息在对等方之间有所不同。

Derive可以是HMACCMAC,并且包含KDF的元素。另请参阅HKDF,这是“扩展然后提取”的最新技术。算法