Шифрование RSA с использованием openssl, переменная длина для зашифрованного текста с PKCS1 Padding

Я пытаюсь зашифровать строку «HELLO», используя RSA-шифрование с PKCS1 Padding. Я использую openssl для создания keypair и выполнения шифрования.

Проблема: я получаю сгенерированный текст с переменной длиной.

Private Key: LS== Public Key: LS== Encrypted Text for HELLO in Run1: XuKAosKxw6BWXcK/w7cgMBww4oCZxLHDgO+sggXigJQR4oC5w7o3SAFbTTHiiJrDsuKJoM6p4oC5YMOf4oCwC8ODYsOa76O/MQ5BAUF2w5xMw7vDrkzigJPDq30Bw4bCoRnDgWrLnHHDukNvdcOuKkLCtsOAw6rigJnDseKAucO6G1EcwqfFkzPDiyLDnAjigKHDmUbDoxHCu8O8WU9LwrXigKDDssOvw7zDrhNfw7gCw7bvo78Jw4hp4oiGc8OrxbhTwrfiiI9mw5xQGgg6wrco76yCw6V1fg7DlDbDknPLnWY7KuKAmuKAnU3DqsOcwqzEsRg7y5g7O3RmdMOcD8OZw4TiiaXDoU7LmcWSw6fDmeKAucWTGBDFkiTiiYjiiJ5JXA3DksOuw4ldd8uH76yCUQwm4oKsw7nDhe+sgR0RUA/iiJ4vH2gTO+KAoW7DlcK/w7o8y5tFZHrCsGfigJrDocKwy5zDjMK7w4pKCibDguKInnkbUuKImsuYy5rigKDCrsO/C1HDo3LCrMOqwrXigJzigJ7DqeKAmuKIj3LDjgnDscOlwrZbDzVZw5PDmXlYO8ORFA== Encrypted Text for HELLO in Run2: E0dedDrigJxBw5jCqhwLRA4yHcOzwqgVa1HCrmkWKcua4omlD+KEoi85G1csw7k= NOTE: All data above is Base64Encoded. 

Я использую приведенный ниже код для создания KeyPair и извлечения Private и Public Keys:

 RSA *rsaKeyPair = NULL; EVP_PKEY *PrivateKey = NULL; rsaKeyPair = RSA_new(); BIGNUM *e = NULL; e = BN_new(); BN_set_word(e, 65537); //Generating KeyPair RSA_generate_key_ex(rsaKeyPair, 2048, e, NULL); PrivateKey = EVP_PKEY_new(); BIO *pri = BIO_new(BIO_s_mem()); BIO *pub = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPrivateKey(pri, rsaKeyPair, NULL, NULL, 0, NULL, NULL); PEM_write_bio_RSAPublicKey(pub, rsaKeyPair); size_t pri_len = BIO_pending(pri); size_t pub_len = BIO_pending(pub); char *pri_key = malloc(pri_len + 1); char *pub_key = malloc(pub_len + 1); BIO_read(pri, pri_key, pri_len); BIO_read(pub, pub_key, pub_len); pri_key[pri_len] = '\0'; pub_key[pub_len] = '\0'; NSString *priK = [[[NSString stringWithFormat:@"%s",pri_key] dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString]; NSString *privateKey = [[priK componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""]; NSString *PKK = [[[NSString stringWithFormat:@"%s",pub_key] componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""]; NSString *pubK = [[PKK dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString]; NSString *publicKey = [[pubK componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""]; //IMP: publicKey is shared along with encrypted text(HELLO string encrypted with PrivateKey) 

Я шифрую HELLO с помощью PrivateKey, используя следующее:

 NSString *myString = @"HELLO"; const char *msg = (const char *)[myString cStringUsingEncoding:NSASCIIStringEncoding];; err = malloc(130); if((encrypt_len = RSA_private_encrypt(strlen(msg), (unsigned char*)msg, (unsigned char*)encrypt, rsaKeyPair, RSA_PKCS1_PADDING)) == -1) { ERR_load_crypto_strings(); ERR_error_string(ERR_get_error(), err); fprintf(stderr, "Error encrypting message: %s\n", err); } NSString *validatorBase64 = [[[NSString stringWithFormat:@"%s",encrypt] dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString]; NSString *validator = [[validatorBase64 componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""]; 

2 Solutions collect form web for “Шифрование RSA с использованием openssl, переменная длина для зашифрованного текста с PKCS1 Padding”

У вас есть проблема в этой строке:

 NSString *validatorBase64 = [[[NSString stringWithFormat:@"%s",encrypt] dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString]; 

потому что encrypt – это двоичные байты, а не строка с нулевым завершением. Вероятно, это приводит к появлению результатов переменной длины.

Вот короткая программа в чистом C, которая использует RSA_private_encrypt / RSA_public_decrypt :

 #include <stdio.h> #include <string.h> #include <openssl/bio.h> #include <openssl/evp.h> #include <openssl/rsa.h> int main() { BIGNUM *e = BN_new(); BN_set_word(e, 65537); RSA *rsaKeyPair = RSA_new(); RSA_generate_key_ex(rsaKeyPair, 2048, e, NULL); BN_free(e); const unsigned char *plaintext = (unsigned char *)"HELLO"; unsigned char crypttext[RSA_size(rsaKeyPair)]; const int cryptLength = RSA_private_encrypt( strlen((const char *)plaintext), plaintext, crypttext, rsaKeyPair, RSA_PKCS1_PADDING); printf("encrypted length: %d\n", cryptLength); printf("encrypted data: "); for (int i = 0; i < cryptLength; ++i) printf("%02x", crypttext[i]); printf("\n"); printf("encrypted data (base64): "); BIO *base64 = BIO_new(BIO_s_mem()); base64 = BIO_push(BIO_new(BIO_f_base64()), base64); BIO_write(base64, crypttext, cryptLength); BIO_flush(base64); char *base64Data; const long base64Length = BIO_get_mem_data(base64, &base64Data); for (int i = 0; i < base64Length; ++i) printf("%c", base64Data[i]); printf("\n"); BIO_free(base64); unsigned char decrypted[RSA_size(rsaKeyPair)]; const int plainLength = RSA_public_decrypt( cryptLength, crypttext, decrypted, rsaKeyPair, RSA_PKCS1_PADDING); printf("decrypted length: %d\n", plainLength); decrypted[plainLength] = 0; printf("decrypted data: %s\n", (const char *)decrypted); RSA_free(rsaKeyPair); return 0; } 

Пример вывода:

 $ ./rsa encrypted length: 256 encrypted data: 2a884725dacdb961a51db22444b23a7802c5c612038ad8067bfe8b2db50e2c110fa2fc198ead4db314b9af57ada233228b7f07e09f821dd1928f2358f337bafa6915ae1f394b787a2250f19ff9e8babf9ffce0d7efebff95be5e017225223c05f8d3f93fa1126a9e77d485b38d01bbdf041fece43a388855695f9acd150f968aa23d0f7c247339f9953074171ad168cb06f2b6ff1c59dbde687a97da4360f0883b2a4d399b5213d3dee9a061ad0335f711acbecb212bc8ec1b5c2a3f9dbfc7d695c3593dc634b8b32727c7072cdcc716dfa2e86732fd54dfdbb193c0b0e0cb6d81f408cc12c4b97308c166dfbb0c8934dcba92d2e528c994ed9f10ec44d51ecb encrypted data (base64): KohHJdrNuWGlHbIkRLI6eALFxhIDitgGe/6LLbUOLBEPovwZjq1NsxS5r1etojMi i38H4J+CHdGSjyNY8ze6+mkVrh85S3h6IlDxn/nour+f/ODX7+v/lb5eAXIlIjwF +NP5P6ESap531IWzjQG73wQf7OQ6OIhVaV+azRUPloqiPQ98JHM5+ZUwdBca0WjL BvK2/xxZ295oepfaQ2DwiDsqTTmbUhPT3umgYa0DNfcRrL7LISvI7BtcKj+dv8fW lcNZPcY0uLMnJ8cHLNzHFt+i6Gcy/VTf27GTwLDgy22B9AjMEsS5cwjBZt+7DIk0 3LqS0uUoyZTtnxDsRNUeyw== decrypted length: 5 decrypted data: HELLO 

@rhashimoto: u действительно помог мне .. Теперь я получаю зашифрованную строку с фиксированной длиной.

Но base64 сгенерированный не совпадает на сервере, возможно, я пересылаю открытый ключ неправильно.

 -(void)generateKeyPairs{ RSA *rsaKeyPair = NULL; EVP_PKEY *PrivateKey = NULL; rsaKeyPair = RSA_new(); BIGNUM *e = NULL; e = BN_new(); BN_set_word(e, 65537); RSA_generate_key_ex(rsaKeyPair, 2048, e, NULL); // Now we need a private key object PrivateKey = EVP_PKEY_new(); BIO *pri = BIO_new(BIO_s_mem()); BIO *pub = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPrivateKey(pri, rsaKeyPair, NULL, NULL, 0, NULL, NULL); PEM_write_bio_RSAPublicKey(pub, rsaKeyPair); size_t pri_len = BIO_pending(pri); size_t pub_len = BIO_pending(pub); char *pri_key = malloc(pri_len + 1); char *pub_key = malloc(pub_len + 1); BIO_read(pri, pri_key, pri_len); BIO_read(pub, pub_key, pub_len); pri_key[pri_len] = '\0'; pub_key[pub_len] = '\0'; NSString *PK = [[[NSString stringWithFormat:@"%s",pri_key] componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""]; NSString *privateKey = [self RemoveKeyLabelFrom:[NSString stringWithFormat:@"%@",PK]]; NSString *PKK = [[[NSString stringWithFormat:@"%s",pub_key] componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""]; NSString *publicKey = [self RemoveKeyLabelFrom:[NSString stringWithFormat:@"%@",PKK]]; NSLog(@"Private Key: %@",privateKey); NSLog(@"Public Key: %@",publicKey); } - (NSString *)RemoveKeyLabelFrom:(NSString *)str { str = [str stringByReplacingOccurrencesOfString:@"-----BEGIN RSA PRIVATE KEY-----" withString:@""]; str = [str stringByReplacingOccurrencesOfString:@"-----END RSA PRIVATE KEY-----" withString:@""]; str = [str stringByReplacingOccurrencesOfString:@"-----BEGIN RSA PUBLIC KEY-----" withString:@""]; str = [str stringByReplacingOccurrencesOfString:@"-----END RSA PUBLIC KEY-----" withString:@""]; return str; } 

Скажите, пожалуйста, что я пропал без вести, чтобы получить правильный открытый ключ.

  • Как создать асимметричную пару ключей RSA в Swift для IOS?
  • iOS: добавление закрытого ключа к устройствам KeyChain
  • SHA256withRSA, что он делает и в каком порядке?
  • Генерировать открытый ключ RSA от модуля и показателя
  • Чтение открытого ключа PEM в iOS
  • NSString для SecKeyRef
  • Генерация открытых ключей RSA - Swift
  • Преобразование NSData в SecKeyRef
  • Разница между кодировкой PKCS1-padding / RSA ios objc и java
  • Создание SecKeyRef из открытого ключа base64 RSA
  • Как создать открытый и закрытый ключи RSA с помощью Swift 3?
  • Interesting Posts
    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.