在C中使用OpenSSL库进行解密时,PEM_read_RSAPrivateKey返回“非法搜索”

时间:2012-10-14 19:23:18

标签: c openssl rsa

这个问题让我疯了! :) 我正在生成几个公钥/私钥对,但是当我去加载私钥时我得到一个错误。我正在使用C.注意我确实在密钥上使用密码“password”,它被设置为#define但我已经尝试将其作为字符串手动放入,没有区别。以下是我如何生成密钥:

FILE *fp;
OpenSSL_add_all_algorithms();
RSA *rsa=NULL;
unsigned char seed[KEYSIZE];
int i;

//Seed PRNG
srand(time(NULL));
RAND_bytes(seed, KEYSIZE - 1);

//Generate a key
if ((rsa=RSA_generate_key(KEYSIZE,65537,NULL,NULL)) == NULL) ERR_get_error();

//Write the public key
fp = fopen(pubkey,"w");
if (!PEM_write_RSA_PUBKEY(fp, rsa)) {
    printf("Error writing public key\n"); exit(1);
}
fclose(fp);

//Write the private key
fp = fopen(privkey,"w");
if (!PEM_write_RSAPrivateKey(fp, rsa, EVP_des_ede3_cbc(), NULL, 0, NULL, PASSWORD))
{
   printf("Error writing private key\n"); exit(1);
}
fclose(fp);

这样就完成了,我最终得到了适当位置的文件,看起来很棒。我还使用这些文件在命令行上成功加密/解密,所以我知道它们有效!

以下是我如何加载私钥:

static void decrypt(int locale) {
FILE *key; 
RSA *rsa;

key = fopen(PRIVATEKEY, "r");
if (key == NULL) perror("Error reading private key");

rsa = PEM_read_RSAPrivateKey(key, NULL, NULL, PASSWORD); // THIS BREAKS!
if (rsa == NULL) perror("Private Key not valid");  // I always get this error :(

if (rsa != NULL) RSA_free(rsa);
fclose(key);}

有什么建议吗?我浏览了源文件rsa.c,这基本上就是他们在那里做的,除了他们使用BIO而不是freads。我不明白为什么我的方式不应该工作!

以下是strace输出的相关部分:

open("/opt/evoting/keys/priv/mix1.priv", O_RDONLY) = 15
fstat64(15, {st_mode=S_IFREG|0644, st_size=1751, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb773c000
read(15, "-----BEGIN RSA PRIVATE KEY-----\n"..., 4096) = 1751
dup(2)                                  = 16
fcntl64(16, F_GETFL)                    = 0x2 (flags O_RDWR)
fstat64(16, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb773b000
_llseek(16, 0, 0xbfba00d0, SEEK_CUR)    = -1 ESPIPE (Illegal seek)
write(16, "Private Key not valid: Resource "..., 56Private Key not valid: Resource     temporarily unavailable ) = 56
close(16)                               = 0
munmap(0xb773b000, 4096)                = 0
close(15)                               = 0
munmap(0xb773c000, 4096)                = 0

此外,perror会产生错误“资源不可用”。我不确定那是什么意思,但是我将我的软硬度重置为非常高并且什么也没做。我将函数复制到自己的文件中并对其进行编译,并且它不会产生错误(但仍然无法读取密钥)。

2 个答案:

答案 0 :(得分:7)

啊哈!好吧,我刚学到了很多关于解决这些问题的知识,希望它能帮助其他人。我的大多数信息来自这个主题:http://readlist.com/lists/openssl.org/openssl-users/2/10340.html

基本上我不需要使用perror而是使用ERR_print_errors_fp(stderr)。这给了我一个像这样的实际错误信息:

3077973640:error:0906B072:lib(9):func(107):reason(114):pem_lib.c:530:

然后我使用了命令:openssl errstr 0906B072并获得了:

error:0906B072:PEM routines:PEM_get_EVP_CIPHER_INFO:unsupported encryption

这基本上让我回到创建我的密钥对,我指定了CBC:EVP_des_ede3_cbc(),这是RSA不支持的。你去吧!

答案 1 :(得分:6)

我找到了解决方案 - 您只需在

之前调用OpenSSL_add_all_ciphers()功能
  

OpenSSL_add_all_ciphers()将所有加密算法添加到表中,包括基于密码的加密算法。

     

密码和摘要查找函数用于库的许多部分。如果表没有初始化,则几个函数会出错,并抱怨他们找不到算法。这包括PEM,PKCS#12,SSL和S / MIME库。这是OpenSSL邮件列表中的常见查询。

     

在所有算法中调用OpenSSL_add_all_algorithms()链接:因此,静态链接的可执行文件可能非常大。如果这很重要,可以只添加所需的密码和摘要。

http://www.openssl.org/docs/crypto/x509.html#