这是一个系统的存根,它将在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
}
以下是我的问题:
感谢您的时间。
答案 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_byes
和EVP_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
可能来自密钥交换或密钥协议。
key1
,key2
和key3
会有所不同,因为(1)调用之间的使用情况不同,以及(2)其他区分信息在对等方之间有所不同。
Derive
可以是HMAC
或CMAC
,并且包含KDF的元素。另请参阅HKDF,这是“扩展然后提取”的最新技术。算法