(不要与DES算法子密钥生成混淆)
(编辑:更多例子)
我这样做是作为学校作业的一部分,我需要在C中重新编写部分OpenSSL,特别是那些与PKI密码系统有关的部分。到目前为止,我已经从头开始使用ecb
,cbc
,3des-ecb
和3des-cbc
操作模式重新编写核心DES算法。该项目的其他部分包括MD5和SHA256。该项目的这一部分侧重于RSA密钥生成,操作和使用。
RSA密钥操作的一部分包括使用密码短语加密给定密钥
(不像我以前用DES那样单独使用纯key
+ initial vector
)
这需要将用户输入密码短语转换为DES密钥(以及根据需要可选的附加IV),然后使用它来加密RSA密钥。我知道我正在寻找的函数的一般术语是 PBKDF ,或基于密码的密钥派生函数。但是,我无法(通过搜索OpenSSL或google的man
页面)找到OpenSSL中用于密钥派生的确切函数(或函数)。
运行以下没有密码的命令会生成未加密的RSA密钥example_plain_key
。
ssh-keygen -t rsa -f example_plain_key
然后运行以下命令将使用example_plain_key
密码以des
模式加密ecb
。每个命令都将加密版本输出到新文件,因此它不会更改原始文件。对两个命令使用相同的密码(例如,密码)。
openssl rsa -DES-ECB -in id_rsa -out id_rsa_1
openssl rsa -DES-ECB -in id_rsa -out id_rsa_2
您可以使用head id_rsa
和head id_rsa_1
查看加密密钥如何更改标头。如果您将两个新密钥与
diff id_rsa_1 id_rsa_2
它们在标题和格式中是相同的,但即使使用相同的密码,密钥本身也会以不同方式加密。不同之处在于密钥生成(我相信)每次运行时都会生成一个新的随机盐。我会假设哈希算法和迭代次数是相同的。此外,与unix机器上的/etc/shadow
不同,盐似乎不会与密钥一起存储(或者至少我不知道如何阅读它)。
更具体DES的例子是:
openssl des -P
使用相同的密码多次运行上述命令将始终导致不同的密钥和iv,可能是因为盐不同。
我没有运气就浏览了OpenSSL的来源。如果绝对必要,我会进行详尽的搜索,但the code不是最易读或最易搜索的。
最有帮助的发现使我相信我正在寻找的示例原型看起来像这样:
#include <unistd.h>
#include <stdio.h>
#include <pwd.h>
// #include <something_else_maybe.h>
int main(void)
{
int num_iterations = 1000;
char *salt;
char *passphrase;
char *key;
passphrase = getpass("Password: ");
salt = get_some_random_bytes(8); // assumed arbitrary length
// the function in question
key = example_pbkdf(md5_function, num_iterations, salt, 8, passphrase, strlen(passphrase));
printf("Key (in hexadecimal or otherwise) is: %s\n", key);
free(key);
free(passphrase);
free(salt);
return (0);
}
(知道在哪里寻找这些答案比答案本身更有价值,但是所有的帮助都很受欢迎。我确实需要C中的标题/源/原型/等。)
答案 0 :(得分:-1)
我在security stack exchange找到了这个问题的答案。
谢谢你Grant Sanders,你到函数源的链接帮助我指出了函数的来源(我计划拆除和识别),但事实证明实际过程要简单得多。尽管定义PBKDF
具有多个迭代和可变散列函数,但OpenSSL的实现只使用MD5的一次迭代以及密码和原始盐(可能是硬编码的)。
我写了一个快速的脚本,证明了上面的答案(至少对于DES)here。