2012-05-24 9 views
5

Estoy intentando generar una clave pública rsa a partir de un tipo de módulo char [], y ahora el exponente es RSA_F4 (65537); Pero cuando intento generar mi clave pública usando estos valores para "n" y "e", la RSA_public_encrypt, devuelve -1;Cómo crear una clave pública RSA a partir de un módulo y exponente char * sin signo 65537 (RSA_F4)

Gracias!

Mi código:

#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

usted parece leer su módulo en 'x', que nunca se declara, dejando' modul' como 0. también nunca ponga el módulo en 'pubkey', por lo es probable que aún esté en blanco, lo que le da un error cuando Intenta llamar a 'RSA_public_encrypt'. Si desea ayuda real, debe publicar el código real que ha intentado compilar y ejecutar. –

+0

Lo siento, pero mi última publicación fue insertada por error. –

Respuesta

2

Es posible que desee algo que se parece más a:

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"); 

edición

Su código funciona bien, a excepción de la comprobación de errores. RSA_public_encrypt devuelve el tamaño del texto cifrado en caso de éxito, no es 0, por lo que para hacer el código anterior trabajo, añadir una línea <= 0 prueba para if:

if (RSA_public_encrypt(....) <= 0) 
+0

Lo siento pero mi última publicación fue insertada por error. Ahora que mi pregunta está completa, ¿puedes salvarme? ¡Gracias! –

1

Aquí hay un código C, que hace el truco:

#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; 
} 

Vea este enlace para más información: http://www.techper.net/2012/06/01/converting-rsa-public-key-modulus-and-exponent-into-pem-file/

+0

Hola, soy capaz de escribir pem público pero obtener una clave privada en blanco. aquí está mi código - char szModulus = "1162"; char * szExp = "827655"; RSA rsa1 = RSA_new(); int ret = BN_hex2bn (& rsa1-> n, szModulus); ret = BN_hex2bn (& rsa1-> d, szExp); ARCHIVO * fp; fp = fopen ("/ Users/ysi/Desktop/privateKey.pem", "wb"); .Por favor, ayúdame. Gracias –

Cuestiones relacionadas