Я пытаюсь использовать пример openssl https://wiki.openssl.org/index.php/EVP_Asymmetric_Encryption_and_Decryption_of_an_Envelope,, и там были найдены слабые ключи.
Существует 3 пользователя.Каждый пользователь генерирует свои собственные открытые и закрытые ключи RSA.Затем с помощью envelope_seal сообщение становится зашифрованным, и каждый пользователь получает зашифрованный симметричный ключ.
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
typedef unsigned char byte;
#define error(message)\
printf("ERROR: to %s!\n", message);\
exit(0);
// generate rsa's private and public key pair
void generate_rsa_keys(int bits, RSA **rsa_private, RSA **rsa_public) {
BIGNUM *bne = BN_new();
BN_set_word(bne, RSA_F4);
RSA *rsa = NULL;
rsa = RSA_new();
if (1 != RSA_generate_key_ex(rsa, bits, bne, NULL)) {
error("run RSA_generate_key, and create \'rsa\'");
}
*rsa_private = RSAPrivateKey_dup(rsa);
*rsa_public = RSAPublicKey_dup(rsa);
BN_free(bne);
RSA_free(rsa);
}
//
void envelope_seal(const EVP_CIPHER *cipher, byte **enc_key, int *enc_key_length, byte *iv, EVP_PKEY **pkeys, int pkeys_length, byte *message, int message_length, byte **enc, int *enc_length) {
int len = 0;
EVP_CIPHER_CTX *ctx;
if (!(ctx = EVP_CIPHER_CTX_new())) {
error("create and initialise the cipher context \'ctx\'");
}
if (pkeys_length != EVP_SealInit(ctx, cipher, enc_key, enc_key_length, iv, pkeys, pkeys_length)) {
error("init the seal operation");
}
if (1 != EVP_SealUpdate(ctx, *enc, enc_length, message, message_length)) {
error("provide the \'message\' to be encrypted");
}
if (1 != EVP_SealFinal(ctx, *enc + *enc_length, &len)) {
error("finalize the encryption");
}
*enc_length += len;
EVP_CIPHER_CTX_free(ctx);
}
void envelope_open(const EVP_CIPHER *cipher, byte *enc_key, int enc_key_length, byte *iv, EVP_PKEY *pkey_private, byte *enc, int enc_length, byte **dec, int *dec_length) {
int len = 0;
EVP_CIPHER_CTX *ctx;
if (!(ctx = EVP_CIPHER_CTX_new())) {
error("create and initialise the cipher context \'ctx\'");
}
if (1 != EVP_OpenInit(ctx, cipher, enc_key, enc_key_length, iv, pkey_private)) {
error("init the open operation");
}
if (1 != EVP_OpenUpdate(ctx, *dec, dec_length, enc, enc_length)) {
error("provide the \'message\' to be decrypted");
}
if (1 != EVP_OpenFinal(ctx, *dec + *dec_length, &len)) {
error("finalize the decryption");
}
*dec_length += len;
EVP_CIPHER_CTX_free(ctx);
}
int main(int argc, char *argv[]) {
// RSA seeding
int seed[] = {0, 1, 2, 3, 4, 5, 6, 7};
RAND_seed(seed, 8);
// simple message to encrypt.
byte *message = "The quick brown fox jumps over the lazy dog.";
size_t message_length = strlen(message);
// algorithm aes cbc, because we do not want to handle iv
const EVP_CIPHER *cipher = EVP_aes_256_cbc();
// user 1
RSA *rsa_private0 = NULL, *rsa_public0;
generate_rsa_keys(2048, &rsa_private0, &rsa_public0);
EVP_PKEY *pkey_private0 = EVP_PKEY_new(), *pkey_public0 = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey_private0, RSAPrivateKey_dup(rsa_private0));
EVP_PKEY_assign_RSA(pkey_public0, RSAPublicKey_dup(rsa_public0));
// user 2
RSA *rsa_private1 = NULL, *rsa_public1;
generate_rsa_keys(3072, &rsa_private1, &rsa_public1);
EVP_PKEY *pkey_private1 = EVP_PKEY_new(), *pkey_public1 = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey_private1, RSAPrivateKey_dup(rsa_private1));
EVP_PKEY_assign_RSA(pkey_public1, RSAPublicKey_dup(rsa_public1));
// user 3
RSA *rsa_private2 = NULL, *rsa_public2;
generate_rsa_keys(4096, &rsa_private2, &rsa_public2);
EVP_PKEY *pkey_private2 = EVP_PKEY_new(), *pkey_public2 = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey_private2, RSAPrivateKey_dup(rsa_private2));
EVP_PKEY_assign_RSA(pkey_public2, RSAPublicKey_dup(rsa_public2));
// allocating space for data
int pkeys_length = 3;
EVP_PKEY **pkeys = (EVP_PKEY **)calloc(sizeof(EVP_PKEY *), pkeys_length);
pkeys[0] = pkey_public0;
pkeys[1] = pkey_public1;
pkeys[2] = pkey_public2;
byte **enc_keys = (byte **)calloc(sizeof(byte *), pkeys_length);
enc_keys[0] = (byte *)OPENSSL_malloc(RSA_size(rsa_public0));
enc_keys[1] = (byte *)OPENSSL_malloc(RSA_size(rsa_public1));
enc_keys[2] = (byte *)OPENSSL_malloc(RSA_size(rsa_public2));
int *enc_key_lengths = (int *)calloc(sizeof(int), pkeys_length);
enc_key_lengths[0] = RSA_size(rsa_public0);
enc_key_lengths[1] = RSA_size(rsa_public1);
enc_key_lengths[2] = RSA_size(rsa_public2);
int iv_length = EVP_CIPHER_iv_length(cipher);
byte *iv = (byte *)OPENSSL_malloc(iv_length);
// encrypting message
int enc_length = 0;
byte *enc = (byte *)OPENSSL_malloc(1024);
envelope_seal(cipher, enc_keys, enc_key_lengths, iv, pkeys, pkeys_length, message, message_length, &enc, &enc_length);
// each user decrypt his key
int dec_key_length0 = EVP_CIPHER_key_length(cipher);
byte *dec_key0 = (byte *)OPENSSL_malloc(dec_key_length0);
RSA_private_decrypt(enc_key_lengths[0], enc_keys[0], dec_key0, rsa_private0, RSA_PKCS1_OAEP_PADDING);
printf("The 1 user:\n");
BIO_dump_fp(stdout, enc_keys[0], enc_key_lengths[0]);
printf("key:\n");
BIO_dump_fp(stdout, dec_key0, dec_key_length0);
int dec_key_length1 = EVP_CIPHER_key_length(cipher);
byte *dec_key1 = (byte *)OPENSSL_malloc(dec_key_length1);
RSA_private_decrypt(enc_key_lengths[1], enc_keys[1], dec_key1, rsa_private1, RSA_PKCS1_OAEP_PADDING);
printf("The 2 user:\n");
BIO_dump_fp(stdout, enc_keys[1], enc_key_lengths[1]);
printf("key:\n");
BIO_dump_fp(stdout, dec_key1, dec_key_length1);
int dec_key_length2 = EVP_CIPHER_key_length(cipher);
byte *dec_key2 = (byte *)OPENSSL_malloc(dec_key_length2);
RSA_private_decrypt(enc_key_lengths[2], enc_keys[2], dec_key2, rsa_private2, RSA_PKCS1_OAEP_PADDING);
printf("The 3 user:\n");
BIO_dump_fp(stdout, enc_keys[2], enc_key_lengths[2]);
printf("key:\n");
BIO_dump_fp(stdout, dec_key2, dec_key_length2);
// each user decrypt message with his private key and provided symm. enc key.
printf("Dec message:\n");
int dec_length0 = 0;
byte *dec0 = (byte *)OPENSSL_malloc(1024);
envelope_open(cipher, enc_keys[0], enc_key_lengths[0], iv, pkey_private0, enc, enc_length, &dec0, &dec_length0);
printf("The 1 user:\n");
BIO_dump_fp(stdout, enc, enc_length);
BIO_dump_fp(stdout, dec0, dec_length0);
int dec_length1 = 0;
byte *dec1 = (byte *)OPENSSL_malloc(1024);
envelope_open(cipher, enc_keys[1], enc_key_lengths[1], iv, pkey_private1, enc, enc_length, &dec1, &dec_length1);
printf("The 2 user:\n");
BIO_dump_fp(stdout, enc, enc_length);
BIO_dump_fp(stdout, dec1, dec_length1);
int dec_length2 = 0;
byte *dec2 = (byte *)OPENSSL_malloc(1024);
envelope_open(cipher, enc_keys[2], enc_key_lengths[2], iv, pkey_private2, enc, enc_length, &dec2, &dec_length2);
printf("The 3 user:\n");
BIO_dump_fp(stdout, enc, enc_length);
BIO_dump_fp(stdout, dec2, dec_length2);
return 0;
}
Симметричный ключ для пользователя 1:
0000 - 70 12 3e a1 a3 55 00 00-00 00 00 00 00 00 00 00 p.>..U..........
0010 - 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Симметричный ключ дляпользователь 2:
0000 - 20 37 3e a1 a3 55 00 00-00 00 00 00 00 00 00 00 7>..U..........
0010 - 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Симметричный ключ для пользователя 3:
0000 - 10 ef 3d a1 a3 55 00 00-00 00 00 00 00 00 00 00 ..=..U..........
0010 - 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Один и тот же симметричный ключ ожидался для каждого пользователя.Первые байты ключей отличаются, и большинство байтов - нули.Как правильно выполнить это действие?Я правильно получаю ключ RSA, не так ли?