我正在尝试从模数类型char []生成一个rsa公钥,现在我的指数是RSA_F4(65537); 但是,当我尝试使用“n”和“e”的值生成我的公钥时,RSA_public_encrypt,返回-1;
谢谢!
我的代码:
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <crypt.h>
#include <iostream>
#include <stdlib.h>
#include <openssl/rsa.h>
#include <openssl/aes.h>
#include <openssl/opensslconf.h>
#include <openssl/engine.h>
#include <openssl/pem.h>
#include <openssl/rc4.h>
using namespace std;
int main(void)
{
//modulus in format char hex;
char key[] = "C0E7FC730EB5CF85B040EC25DAEF288912641889AD651B3707CFED9FC5A1D3F6C40062AD46E3B3C3E21D4E71CC4800C80226D453242AEB2F86D748B41DDF35FD";
char palavra[] = "teste";
char crip[512];
int ret;
RSA * pubkey = RSA_new();
BIGNUM * modul = BN_new();
BIGNUM * expon = BN_new();
BN_hex2bn(&modul, (const char *) key);
BN_hex2bn(&expon, "010001");
cout << "N KEY: " << BN_bn2hex(modul) << endl;
cout << "E KEY: " << BN_bn2hex(expon) << endl;
pubkey->n = modul;
pubkey->e = expon;
cout << "N PUB KEY: " << BN_bn2hex(pubkey->n) << endl;
cout << "E PUB KEY: " << BN_bn2hex(pubkey->e) << endl;
if (RSA_public_encrypt(strlen((const char *) palavra), (const unsigned char *) palavra, (unsigned char *) crip, pubkey, RSA_PKCS1_PADDING ))
{
printf("ERRO encrypt\n");
}
else
{
printf("SUC encrypt\n");
}
return 0;
}
答案 0 :(得分:4)
你可能想要看起来更像的东西:
RSA *pubkey = RSA_new();
int len = BN_hex2bn(&pubkey->n, (const char *)p);
if (len == 0 || p[len])
fprintf(stderr, "'%s' does not appear to be a valid modulus\n", p);
BN_hex2bn(&pubkey->e, "010001");
修改强>
除错误检查外,您的代码工作正常。 RSA_public_encrypt在成功时返回密文的大小,而不是0,因此要使上面的代码工作,请向<= 0
行添加if
测试:
if (RSA_public_encrypt(....) <= 0)
答案 1 :(得分:1)
这是一些C代码,它可以解决这个问题:
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bn.h>
#include <openssl/pem.h>
// cheating, .. ignoring deprecation warnings
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
unsigned char *base64_decode(const char* base64data, int* len) {
BIO *b64, *bmem;
size_t length = strlen(base64data);
unsigned char *buffer = (unsigned char *)malloc(length);
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new_mem_buf((void*)base64data, length);
bmem = BIO_push(b64, bmem);
*len = BIO_read(bmem, buffer, length);
BIO_free_all(bmem);
return buffer;
}
BIGNUM* bignum_base64_decode(const char* base64bignum) {
BIGNUM* bn = NULL;
int len;
unsigned char* data = base64_decode(base64bignum, &len);
if (len) {
bn = BN_bin2bn(data, len, NULL);
}
free(data);
return bn;
}
EVP_PKEY* RSA_fromBase64(const char* modulus_b64, const char* exp_b64) {
BIGNUM *n = bignum_base64_decode(modulus_b64);
BIGNUM *e = bignum_base64_decode(exp_b64);
if (!n) printf("Invalid encoding for modulus\n");
if (!e) printf("Invalid encoding for public exponent\n");
if (e && n) {
EVP_PKEY* pRsaKey = EVP_PKEY_new();
RSA* rsa = RSA_new();
rsa->e = e;
rsa->n = n;
EVP_PKEY_assign_RSA(pRsaKey, rsa);
return pRsaKey;
} else {
if (n) BN_free(n);
if (e) BN_free(e);
return NULL;
}
}
void assert_syntax(int argc, char** argv) {
if (argc != 4) {
fprintf(stderr, "Description: %s takes a RSA public key modulus and exponent in base64 encoding and produces a public key file in PEM format.\n", argv[0]);
fprintf(stderr, "syntax: %s <modulus_base64> <exp_base64> <output_file>\n", argv[0]);
exit(1);
}
}
int main(int argc, char** argv) {
assert_syntax(argc, argv);
const char* modulus = argv[1];
const char* exp = argv[2];
const char* filename = argv[3];
EVP_PKEY* pkey = RSA_fromBase64(modulus, exp);
if (pkey == NULL) {
fprintf(stderr, "an error occurred :(\n");
return 2;
} else {
printf("success decoded into RSA public key\n");
FILE* file = fopen(filename, "w");
PEM_write_PUBKEY(file, pkey);
fflush(file);
fclose(file);
printf("written to file: %s\n", filename);
}
return 0;
}
有关详细信息,请参阅此链接:http://www.techper.net/2012/06/01/converting-rsa-public-key-modulus-and-exponent-into-pem-file/