我正在尝试生成一个2048位RSA私钥,该密钥在FIPS模式下使用AES256CBC密码加密。我在这里使用OpenSSL 1.0.2l。我尝试了最新的1.0.2快照,但没有任何区别。
我的问题是PEM_write_bio_RSAPrivateKey没有返回1并且我收到此错误:
26660:error:0607606B:digital envelope routines:PKCS5_v2_PBE_keyivgen:unsupported cipher:.\crypto\evp\p5_crpt2.c:229:
26660:error:06074078:digital envelope routines:EVP_PBE_CipherInit:keygen failure:.\crypto\evp\evp_pbe.c:197:
26660:error:23077073:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 algor cipherinit error:.\crypto\pkcs12\p12_decr.c:87:
26660:error:2306C067:PKCS12 routines:PKCS12_item_i2d_encrypt:encrypt error:.\crypto\pkcs12\p12_decr.c:188:
26660:error:2307D067:PKCS12 routines:PKCS8_encrypt:encrypt error:.\crypto\pkcs12\p12_p8e.c:96:
代码:
#include <stdio.h>
#include <tchar.h>
#include <cassert>
#include <memory>
#include <io.h>
#include <fcntl.h>
#include <iostream>
#include <string>
#include <openssl/crypto.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/x509.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/fips.h>
using std::unique_ptr;
#define ASSERT assert
using BN_ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>;
using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>;
using EVP_KEY_ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
using BIO_FILE_ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
using BIO_MEM_ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
using namespace std;
int main(int argc, char* argv[])
{
int rc;
//PART 1: Enter FIPS mode
CRYPTO_malloc_init();
if (0 == FIPS_mode())
{
printf("FIPS_mode says FIPS not set.\n");
}
rc = FIPS_mode_set(1);
if (rc != 1)
{
printf("FIPS_mode_set failed.\n");
ERR_load_crypto_strings();
ERR_print_errors_fp(stderr);
getchar();
exit(1);
}
else
{
printf("FIPS_mode_set worked.\n");
}
//PART 2: Make the CA Private Key
char filename_ca[] = "C:\\Users\\jlaird\\source\\repos\\keygen_sample\\Release\\ca.key.pem";
char unsigned password_ca[] = "capass";
RSA_ptr rsa(RSA_new(), ::RSA_free);
BN_ptr bn(BN_new(), ::BN_free);
//binary input/output file access
BIO_FILE_ptr pem5(
BIO_new_file(
filename_ca, //file name
"w+" //access mode
),
::BIO_free
);
BIO_MEM_ptr bio(BIO_new(BIO_s_mem()), ::BIO_free);
//allocate a big number
rc = BN_set_word(
bn.get(),
RSA_F4
);
//success is indicated by a value of 1
if (rc == 1)
{
printf("BN_set_word worked\n");
}
else
{
printf("FAIL\n");
}
//Generate key
rc = RSA_generate_key_ex(
rsa.get(), //pointer to rsa key
2048, //desired size of key in bits
bn.get(), //get pointer to our big number
NULL //progress callback (we don't care so NULL)
);
//success is indicated by a value of 1
if (rc == 1)
{
printf("RSA_generate_key_ex worked\n");
}
else
{
printf("FAIL\n");
}
rc = RSA_print(bio.get(), rsa.get(), 0);
//success is indicated by a value of 1
if (rc == 1)
{
printf("RSA_print worked\n");
}
else
{
printf("FAIL\n");
}
BUF_MEM* mem = NULL;
BIO_get_mem_ptr(bio.get(), &mem);
ASSERT(mem != NULL);
string s;
if (mem->data && mem->length)
s.assign(mem->data, mem->length);
if (s.length())
cout << s << endl;
else
cout << "Failed to retrieve key" << endl;
// Convert RSA to PKEY
//allocate RSA to PKEY memory
EVP_KEY_ptr pkey(
EVP_PKEY_new(),
::EVP_PKEY_free
);
printf("Convert RSA to PKEY.\n");
//get our private key from the rsa key
rc = EVP_PKEY_set1_RSA(
pkey.get(),
rsa.get()
);
//success is indicated by a value of 1
if (rc == 1)
{
printf("EVP_PKEY_set1_RSA worked\n");
}
else
{
printf("FAIL\n");
}
printf("get our private key from the rsa key.\n");
//Write private key
rc = PEM_write_bio_RSAPrivateKey(
pem5.get(), //binary file pointer
rsa.get(), //key in use
EVP_aes_256_cbc(), //cipher
NULL,
0,
NULL,
password_ca
);
//success is indicated by a value of 1
if (rc == 1)
{
printf("PEM_write_bio_RSAPrivateKey worked\n");
}
else
{
printf("PEM_write_bio_RSAPrivateKey FAIL\n");
ERR_load_crypto_strings();
ERR_print_errors_fp(stderr);
}
printf("done!.\n");
getchar();
return 0;
}
程序的完整输出:
FIPS_mode says FIPS not set.
FIPS_mode_set worked.
BN_set_word worked
RSA_generate_key_ex worked
RSA_print worked
Private-Key: (2048 bit)
modulus:
00:c4:30:0c:a4:ce:25:6c:13:e9:b8:6b:aa:f4:50:
e4:f4:bb:af:ae:cd:4a:b8:0e:a0:35:01:74:ac:d0:
58:96:cc:0d:48:0e:51:6a:00:77:5e:6b:f6:33:0a:
10:1c:fc:8c:5e:67:5c:d3:c0:e2:1b:98:d8:98:9e:
82:83:88:83:4e:35:6d:4e:a5:b4:3f:09:6b:56:b8:
d2:b1:67:3f:d2:c6:79:f6:90:5e:18:1b:39:98:9d:
89:f9:cd:1d:21:d9:0f:bd:ae:83:38:17:83:98:9f:
6b:53:16:05:b3:dd:4f:00:f5:d6:27:83:84:c2:ce:
03:aa:5e:0f:ba:51:a9:50:1d:35:3f:8c:76:8a:bb:
78:54:ff:e3:11:9d:7c:fd:09:ac:5e:8c:57:84:ca:
20:11:92:39:34:e5:8a:15:68:33:c1:90:e2:d2:03:
d2:8b:e4:b6:77:5f:2c:17:93:81:cf:0f:5c:13:d2:
bc:ae:72:2d:47:eb:ca:0d:cd:19:76:4d:75:5d:cd:
70:1b:aa:c4:96:cf:e7:8f:d3:36:83:6f:c3:30:65:
02:b2:cc:9a:c0:a5:5b:bb:53:09:66:01:12:4e:d7:
6c:44:e8:62:a4:24:a6:21:bf:da:7e:d5:68:c4:94:
40:7f:ba:25:47:92:ea:97:fd:99:17:db:76:b9:69:
52:99
publicExponent: 65537 (0x10001)
privateExponent:
11:1f:1e:63:5d:a8:4f:6b:d7:78:64:51:19:9c:5b:
b6:ee:10:51:81:92:15:49:15:7b:3a:c2:cb:78:2d:
5b:0f:b8:d3:02:88:e1:66:e4:04:06:09:09:00:46:
52:b9:49:a8:cd:7d:80:ef:72:ec:34:a5:26:80:a2:
e4:46:cc:2a:cd:a7:d9:f6:c5:29:c1:31:30:72:d5:
d4:6c:ad:d9:bf:bf:92:20:9c:4d:9f:46:a2:06:91:
ad:8e:d4:8d:89:2b:82:02:d2:69:d9:47:7f:50:de:
65:74:65:10:02:ee:eb:a7:08:c7:0f:07:cd:96:7c:
24:68:ac:17:b7:1b:bf:25:7e:46:52:5b:33:13:9c:
0b:48:1f:f9:47:cf:09:ed:5d:4d:18:85:d2:49:30:
94:1c:bb:25:7b:bc:63:31:93:c3:17:f7:b8:d5:77:
6d:2b:36:de:b1:d4:07:e4:ce:9c:ca:29:ef:dd:0a:
3f:60:4a:80:ac:a8:8e:81:95:21:35:6a:49:c5:0c:
e3:2f:50:59:7e:c3:73:3e:ac:98:29:15:57:4b:ad:
fc:70:88:9d:fc:50:39:69:a9:a4:ee:80:db:4e:36:
70:dd:a1:d6:2c:79:77:9d:0d:c3:ef:d2:5e:15:d4:
77:e3:b1:20:12:c6:59:6e:41:d9:ef:9e:8b:a4:13:
19
prime1:
00:e7:9c:27:77:b9:5c:72:0e:81:2e:fb:2f:46:e4:
a8:0e:af:31:63:31:86:d2:2c:71:46:1f:2a:fd:30:
5c:44:45:02:8b:eb:0e:b7:50:9d:25:e2:0b:3a:07:
2f:74:84:48:f0:d3:83:68:bf:6f:e1:59:c4:b4:88:
40:0d:89:57:6d:fe:23:82:af:de:b4:25:ac:6c:76:
26:ce:c7:e1:b7:f9:78:9d:2b:a7:87:25:ce:db:9a:
b4:b7:cb:e6:3d:a1:33:a7:dc:15:a3:5a:99:7c:cc:
b1:2d:e9:c3:72:a3:e6:25:f0:5e:c5:77:47:9e:2c:
8f:51:da:81:62:79:41:98:fd
prime2:
00:d8:d8:f7:22:11:96:35:07:fb:30:8b:70:d0:bf:
fc:7e:ab:2d:9d:f8:94:92:12:74:b4:69:97:1b:5d:
c3:7e:a9:d7:8d:23:04:0b:56:04:4f:fa:40:3d:cf:
18:2f:53:bc:a6:bc:23:19:d1:4f:3e:36:90:d6:f0:
e6:4a:4e:8e:6f:12:87:52:51:f0:90:53:d0:f8:44:
d6:8d:9b:35:5a:7d:09:a8:0e:9b:87:76:8a:94:5e:
ed:a1:22:80:71:8b:98:e6:f0:09:91:70:b1:a5:e4:
9f:12:96:be:a6:a9:74:8a:83:e4:33:cd:b3:db:ff:
71:cd:37:b0:ef:61:3a:10:cd
exponent1:
61:42:98:ec:54:e1:b6:5f:d2:ed:e8:bb:6c:b8:de:
bd:f3:e1:f8:76:b6:d8:11:a3:ab:bf:b0:ec:cb:df:
23:28:1b:ae:a8:11:f0:f7:20:56:e5:3a:b3:ae:8a:
c6:12:3b:13:2e:af:53:50:78:ea:18:29:5b:6a:90:
03:5f:36:60:d1:45:16:3f:46:75:3e:10:cf:27:3a:
9a:c1:23:4f:7f:aa:9f:cd:d2:37:15:b0:6d:55:e5:
27:fd:ae:fd:18:71:b9:be:d9:33:54:fb:79:85:f7:
ad:81:29:fb:3d:4a:8b:8a:0a:32:40:29:ca:09:8a:
51:e4:41:4b:1a:02:6a:fd
exponent2:
00:d2:82:05:9f:60:1d:46:4c:02:30:85:1d:36:b9:
39:9f:aa:03:75:b8:6c:5a:45:6a:5f:fd:a5:40:5e:
cc:ba:78:9c:95:19:aa:02:6b:35:72:82:88:bc:b7:
ff:4d:6a:67:d8:21:09:9e:35:90:4c:df:e1:c9:97:
40:a8:60:0c:6b:8d:3c:2a:d0:fa:cc:d1:61:2a:b2:
80:ea:25:03:2d:5d:f6:f2:db:83:66:84:d0:50:ea:
ba:9a:d3:88:87:31:b2:74:76:0f:83:ce:37:d6:c8:
d3:17:d3:99:2e:e7:90:08:2b:b3:6c:0a:c4:10:cc:
b1:28:3c:69:1a:69:73:59:fd
coefficient:
00:88:66:c0:36:fa:1b:e8:cc:d7:25:13:34:fb:de:
cc:cf:29:1c:e7:b0:0e:26:a1:e2:04:43:c4:a1:17:
41:c0:bc:6a:11:3f:03:67:ae:9a:23:b0:d6:ec:9e:
7b:6c:cf:ce:ba:35:4f:7a:d3:e8:49:45:48:e6:cd:
ea:83:ee:76:34:f0:53:6b:90:72:67:41:a5:0c:ae:
02:25:4e:c5:da:b6:01:fc:13:9f:eb:8d:c4:0b:8d:
a7:a0:4d:c8:8e:a0:56:00:51:31:c9:50:03:37:ab:
85:8f:bf:3c:4e:af:17:11:7a:38:6e:be:ac:94:1a:
dc:54:8e:07:62:fc:b8:1f:04
Convert RSA to PKEY.
EVP_PKEY_set1_RSA worked
get our private key from the rsa key.
PEM_write_bio_RSAPrivateKey FAIL
26660:error:0607606B:digital envelope routines:PKCS5_v2_PBE_keyivgen:unsupported cipher:.\crypto\evp\p5_crpt2.c:229:
26660:error:06074078:digital envelope routines:EVP_PBE_CipherInit:keygen failure:.\crypto\evp\evp_pbe.c:197:
26660:error:23077073:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 algor cipherinit error:.\crypto\pkcs12\p12_decr.c:87:
26660:error:2306C067:PKCS12 routines:PKCS12_item_i2d_encrypt:encrypt error:.\crypto\pkcs12\p12_decr.c:188:
26660:error:2307D067:PKCS12 routines:PKCS8_encrypt:encrypt error:.\crypto\pkcs12\p12_p8e.c:96:
done!.
^我不知道这意味着什么。它就像使用FIPS模式一样不会允许该算法!它会允许什么?
答案 0 :(得分:0)
好的,所以我在更多地考虑错误并发现错误之后想出了这个:
https://wiki.openssl.org/index.php/Manual:OpenSSL_add_all_algorithms(3)
如果在调用FIPS_mode_set(1)后调用OpenSSL_add_all_algorithms(),则PEM_write_bio_RSAPrivateKey可以正常工作。也就是说,这不会引发错误:
rc = PEM_write_bio_RSAPrivateKey(
pem5.get(), //binary file pointer
rsa.get(), //key in use
EVP_aes_256_cbc(), //cipher to use
NULL,
0,
NULL,
password_ca
);
然后我完成后调用EVP_cleanup()以从OpenSSL_add_all_algorithms()调用中释放内存。