Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Перенос с Java на C++ (OpenSSL)


Автор: declonter 10.4.2017, 09:46
Здравствуйте!

Есть код на Java, в котором (насколько я понял) шифруется текстовое сообщение. Не могу перевести на C/C++ с использованием OpenSSL, поскольку не понимаю что именно тут происходит. Ключ заменил на просто строку в Base64. Помогите, написав аналог на C/C++ с использованием OpenSSL, или объяснив, какие действия тут производятся. Чтение документации по OpenSSL не помогло. 

Код

        String message = "message";
        String RSA_Key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsWtXBDNcAAYdCLEituiU7PHC55w7onfIEcG1Z+iES8TQdf1cAZDf+46D1oD31kctjGJyuDydw6owh9HSX5TWmdK6WSrfncjfZrGdS9APA7zvP1UjEbVNu8n8b0RTlKYDC6UL33C7S4KDvzY4Tq72GkVwOky5PlQRdTBsG1Ss9KhMYKMvto9OFM02ZEKGXASKN7/K9kGS9VqjVUp6apfzfTL5FJoDgtwZaWTOqv1mwLn8vaDmJUd4D2wdx2Rmo/EXxVRnAJ0qZAeg4vwDn5MbPkkTo2xOkG5QlSzxJSPtThm9z+MQKI9/2bPxlmg8TrAxCRsKvJ59wsfsx+WjqxjAeQIDAQAB";

        Key key = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(DatatypeConverter.parseBase64Binary(new String(RSA_Key))));
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        System.out.println(Base64.getEncoder().encodeToString(cipher.doFinal(message.getBytes())));

Автор: vpf 10.4.2017, 11:50
на этапе  Key key = ...  вылетает ошибка что ключ слишком короткий...

Автор: declonter 10.4.2017, 12:20
Цитата(vpf @ 10.4.2017,  11:50)
вылетает ошибка что ключ слишком короткий, ну думаю так и есть smile
но синтаксически все верно, проект компилируется.

Ну я так и написал, что ключ заменил на другую строку в base64. 
На java всё работало и раньше, проблема с переносом кода на C/C++ с использованием OpenSSL. По сути, Вы просто переписали исходный код на java, что, к сожалению, мне ничуть не помогло :(

Автор: vpf 10.4.2017, 12:26
Ваша просьба "... или объяснив, какие действия тут производятся..."  Я переписал в более доступном виде на Java.
Но Ваш код на Java не работает. Если он работал раньше, дайте тот код и те данные, где все работало.

Автор: declonter 10.4.2017, 13:17
Цитата(vpf @ 10.4.2017,  12:26)
Ваша просьба "... или объяснив, какие действия тут производятся..."  Я переписал в более доступном виде на Java.
Но Ваш код на Java не работает. Если он работал раньше, дайте тот код и те данные, где все работало.

"какие действия" - это именно криптографическая часть, где ключи, сертификаты (или что там используется) и что с ними просиходит smile. Живые данные ключа (или что там в RSA_Key хранится) дать не могу, поскольку не уверен, что это безопасно.
Опять же криптографическое API java мне не нужно, мне нужно OpenSSL.

Автор: declonter 10.4.2017, 15:24
Решил. Всем спасибо.

Код, аналогичный исходному на C с использованием OpenSSL. Код "грязный", поэтому сгодится только в качестве примера. Публичный ключ RSA валидный (специально сгенерировал).

Код

#include <stdio.h>
#include <string.h>

#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>

char *base64(const unsigned char *input, int length){
  BIO *bmem, *b64;
  BUF_MEM *bptr;

  b64 = BIO_new(BIO_f_base64());
  bmem = BIO_new(BIO_s_mem());
  b64 = BIO_push(b64, bmem);
  BIO_write(b64, input, length);
  BIO_flush(b64);
  BIO_get_mem_ptr(b64, &bptr);

  char *buff = (char *)malloc(bptr->length);
  memcpy(buff, bptr->data, bptr->length-1);
  buff[bptr->length-1] = 0;

  BIO_free_all(b64);

  return buff;
}

int main(int argc, char *argv[]){
    char *key = "-----BEGIN PUBLIC KEY-----\n\
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsWtXBDNcAAYdCLEituiU7PHC55w7onfIEcG1Z+iES8TQdf1cAZDf+46D1oD31kctjGJyuDydw6owh9HSX5TWmdK6WSrfncjfZrGdS9APA7zvP1UjEbVNu8n8b0RTlKYDC6UL33C7S4KDvzY4Tq72GkVwOky5PlQRdTBsG1Ss9KhMYKMvto9OFM02ZEKGXASKN7/K9kGS9VqjVUp6apfzfTL5FJoDgtwZaWTOqv1mwLn8vaDmJUd4D2wdx2Rmo/EXxVRnAJ0qZAeg4vwDn5MbPkkTo2xOkG5QlSzxJSPtThm9z+MQKI9/2bPxlmg8TrAxCRsKvJ59wsfsx+WjqxjAeQIDAQAB\
\n\-----END PUBLIC KEY-----"; // valid Base64-encoded RSA public key
    char message[] = "message";

    do{
        int keysize=strlen(key);
        char * encrypted;

        RSA * rsa = 0;
        int encrypted_length;

        SSL_library_init();
        SSL_load_error_strings();

        BIO *keybio = BIO_new_mem_buf(key, keysize);
        if (0 == keybio){
            printf ("SSL ERROR\n");
            break;
        }
        if (0 == PEM_read_bio_RSA_PUBKEY(keybio, &rsa, 0, 0)){
            printf ("SSL ERROR\n");
            break;
        }
        encrypted=(char*)malloc(RSA_size(rsa));
        encrypted_length = RSA_public_encrypt(strlen(message), (unsigned char*)&message[0], (unsigned char*)encrypted, rsa, RSA_PKCS1_PADDING);
        if (-1 == encrypted_length){
            printf ("SSL ERROR\n");
            break;
        }
        printf("%s\n", base64(encrypted, encrypted_length));
    } while (0);

    printf("Done.\n");
    return (0);

    (void)argc;
    (void)argv;
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)