RSA加密使用openssl,可变长度用于加密文本和PKCS1填充

我正在尝试使用带有PKCS1 Padding的RSA加密来加密字符串“HELLO”。 我使用openssl生成密钥对并执行加密。

问题:我正在获取生成的带有可变长度的加密文本。

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并提取私钥和公钥:

 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) 

我使用以下内容使用PrivateKey加密HELLO:

 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:@""]; 

你有这个问题:

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

因为encrypt是二进制字节而不是以null结尾的字符串。 这可能是导致您的可变长度结果的原因。

这是纯C中使用RSA_private_encrypt / RSA_public_decrypt的简短程序:

 #include  #include  #include  #include  #include  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:你真的帮了我..现在我得到一个修复长度加密的字符串..

但是生成的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; } 

请告诉我,我错过了获得正确的公钥。