我正在尝试实现OpenSSL RSA,以下是我的密钥生成代码:
#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#define SECFILE "sec.pem"
#define PUBFILE "pub.pem"
int main()
{
EVP_PKEY_CTX *ctx;
EVP_PKEY *pkey = NULL;
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
BIO *bio_out = NULL;
FILE *fp;
if (!ctx)
{
perror("Error in CTX \n");
}
if (EVP_PKEY_keygen_init(ctx) <= 0)
{
perror("Error in EVP_PKEY_keygen_init \n");
}
if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0)
{
perror("Error in EVP_PKEY_CTX_set_rsa_keygen_bits \n");
}
/* Generate key */
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
{
/* Error */
perror("Error in EVP_PKEY_keygen \n");
}
fp = fopen(SECFILE, "w");
if ((bio_out = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
{
perror("Error in new BIO \n");
}
BIO_set_flags(bio_out, BIO_FLAGS_WRITE);
EVP_PKEY_print_private(bio_out,pkey,5, NULL);
fclose(fp);
BIO_free(bio_out);
fp = fopen(PUBFILE, "w");
if ((bio_out = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
{
perror("Error in new BIO \n");
}
BIO_set_flags(bio_out, BIO_FLAGS_WRITE);
EVP_PKEY_print_public(bio_out,pkey,5, NULL);
fclose(fp);
BIO_free(bio_out);
return 0;
}
这是pub.pem
:
Public-Key: (2048 bit)
Modulus:
00:be:bc:04:74:39:5b:31:2d:76:bf:41:9a:3e:6e:
d0:cf:8f:c3:25:86:6b:38:ff:58:96:fc:bb:2b:d9:
af:df:fa:bf:aa:1e:c7:58:1d:2b:ce:6c:90:0f:d3:
30:b7:90:fc:1c:7c:84:f3:31:80:3e:04:ad:bd:74:
dc:92:60:01:9e:40:82:31:b3:8d:a5:ac:fb:81:83:
c5:e9:e6:56:0b:f4:df:dd:f3:e4:7f:3b:b6:85:d7:
c9:41:08:3f:bf:15:bd:6d:19:ff:13:fc:4a:52:59:
93:77:b0:be:78:01:da:db:b2:7d:f9:38:98:e0:d2:
45:79:3c:60:0d:a1:65:74:d2:9c:9b:7c:15:2c:e4:
ee:eb:76:52:f3:61:95:8b:d6:fb:5e:fb:f7:c6:40:
70:77:86:fb:60:87:07:f3:58:49:74:d6:0a:cf:d4:
70:09:50:73:20:1e:4e:52:4c:59:34:a0:f5:7a:80:
57:e5:8a:8c:d1:a1:94:a4:ab:75:99:fd:55:62:06:
34:dd:83:00:aa:3f:c8:0a:a1:0e:80:1a:ba:42:6e:
23:37:eb:bd:1f:e4:a2:c4:fa:2a:84:84:e4:dc:ec:
a2:a5:36:2c:c6:cb:28:81:8c:89:15:64:f4:ef:ec:
1e:c8:c3:d5:c2:02:54:ce:bb:72:20:b4:4a:05:2f:
dc:75
Exponent: 65537 (0x10001)
以下是我用于加密的代码:
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <arpa/inet.h> /* For htonl() */
int do_evp_seal(FILE *rsa_pkey_file, FILE *in_file, FILE *out_file)
{
int retval = 0;
RSA *rsa_pkey = NULL;
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_CIPHER_CTX ctx;
unsigned char buffer[4096];
unsigned char buffer_out[4096 + EVP_MAX_IV_LENGTH];
size_t len;
int len_out;
unsigned char *ek;
int eklen;
uint32_t eklen_n;
unsigned char iv[EVP_MAX_IV_LENGTH];
if (!PEM_read_RSA_PUBKEY(rsa_pkey_file, &rsa_pkey, NULL, NULL))
{
fprintf(stderr, "Error loading RSA Public Key File.\n");
// here I am getting this error:
// 140121481717416:error:0906D06C:lib(9):func(109):reason(108):pem_lib.c:696:Expecting: PUBLIC KEY
ERR_print_errors_fp(stderr);
retval = 2;
goto out;
}
EVP_CIPHER_CTX_init(&ctx);
ek = malloc(EVP_PKEY_size(pkey));
if (!EVP_SealInit(&ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &pkey, 1))
{
fprintf(stderr, "EVP_SealInit: failed.\n");
retval = 3;
goto out_free;
}
/* First we write out the encrypted key length, then the encrypted key,
* then the iv (the IV length is fixed by the cipher we have chosen).
*/
eklen_n = htonl(eklen);
if (fwrite(&eklen_n, sizeof eklen_n, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
if (fwrite(ek, eklen, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
if (fwrite(iv, EVP_CIPHER_iv_length(EVP_aes_128_cbc()), 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
/* Now we process the input file and write the encrypted data to the
* output file. */
while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0)
{
if (!EVP_SealUpdate(&ctx, buffer_out, &len_out, buffer, len))
{
fprintf(stderr, "EVP_SealUpdate: failed.\n");
retval = 3;
goto out_free;
}
if (fwrite(buffer_out, len_out, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
}
if (ferror(in_file))
{
perror("input file");
retval = 4;
goto out_free;
}
if (!EVP_SealFinal(&ctx, buffer_out, &len_out))
{
fprintf(stderr, "EVP_SealFinal: failed.\n");
retval = 3;
goto out_free;
}
if (fwrite(buffer_out, len_out, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
out_free:
EVP_PKEY_free(pkey);
free(ek);
out:
return retval;
}
int main(int argc, char *argv[])
{
FILE *rsa_pkey_file;
int rv;
rsa_pkey_file = fopen("pub.pem", "rb");
if (!rsa_pkey_file)
{
fprintf(stderr, "Error loading PEM RSA Public Key File.\n");
exit(2);
}
rv = do_evp_seal(rsa_pkey_file, stdin, stdout);
fclose(rsa_pkey_file);
return rv;
}
为什么PEM_read_RSA_PUBKEY
会返回ERROR: Expecting PUBLIC KEY
?
答案 0 :(得分:0)
好的,我发现自己已经写了PEM_write_bio_PUBKEY(bio_out,pkey );
而不是EVP_PKEY_print_public(bio_out,pkey)