EVP在C上的信封的非对称加密和解密

时间:2019-09-27 07:54:54

标签: c openssl

我正在尝试使用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密钥,不是吗?

1 个答案:

答案 0 :(得分:0)

用于密封的设置使用默认的RSA加密填充RSA_PKCS1_PADDING,但是直接解密使用的是指定的RSA_PKCS1_OEAP_PADDING。这些不兼容。

下面是一个与您相似的简单示例。它表明实际上正在对会话密钥进行适当的加密。这样就消除了填充不一致的主要问题。

代码

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

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/aes.h>
#include <openssl/applink.c>

#define N_KEYS      3
#define N_BITS      3072

#define CHECK_ONE(exp) \
    do { \
        int res = (exp); \
        if (res <= 0) { \
            fprintf(stderr, "ERROR(%d): %s!\n", res, #exp); \
            exit(EXIT_FAILURE); \
        } \
    } while (0)


EVP_PKEY** generate_rsa_keys(int count, int bits)
{
    EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
    EVP_PKEY **keys = OPENSSL_malloc(count * sizeof *keys);
    for (int i = 0; i < count; ++i)
    {
        // initialize generator
        CHECK_ONE( EVP_PKEY_keygen_init(ctx) );
        CHECK_ONE( EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) );

        // generate the key pair
        keys[i] = NULL;
        CHECK_ONE( EVP_PKEY_keygen(ctx, keys + i) );
    }
    EVP_PKEY_CTX_free(ctx);

    return keys;
}

int main()
{
    OpenSSL_add_all_algorithms();
    OpenSSL_add_all_ciphers();

    // used throughout the code below
    BIO *bio = BIO_new_fp(stdout, BIO_NOCLOSE);

    // simple message to encrypt.
    byte message[] = "The quick brown fox jumps over the lazy dog.";
    size_t message_length = strlen(message);

    // algorithm aes256-cbc
    const EVP_CIPHER *cipher = EVP_aes_256_cbc();
    uint8_t iv[AES_BLOCK_SIZE];

    // generate all rsa key pairs
    EVP_PKEY **keys = generate_rsa_keys(N_KEYS, N_BITS);

    // create encryption targets and public-only keys. note the latter here
    //  isn't really necessary, since we could just use the keys[] entries,
    //  but we're simulating what happens when you only have the public keys
    //  for sealing.
    EVP_PKEY **pubkeys = OPENSSL_malloc(N_KEYS * sizeof *pubkeys);
    uint8_t **enc_key = OPENSSL_malloc(N_KEYS * sizeof(*enc_key));
    int *enc_key_length = OPENSSL_malloc(N_KEYS * sizeof *enc_key_length);
    for (int i = 0; i < N_KEYS; ++i)
    {
        RSA* rsa = EVP_PKEY_get1_RSA(keys[i]);
        enc_key[i] = OPENSSL_malloc(RSA_size(rsa));
        pubkeys[i] = EVP_PKEY_new();
        CHECK_ONE( EVP_PKEY_assign_RSA(pubkeys[i], RSAPublicKey_dup(rsa)));
        RSA_free(rsa);
    }

    ////////////////////////////////////////////////////////////////////////////
    // SEAL AND GENERATE SESSION KEY ENCRYPTIONS
    int tmp, encrypted_length = AES_BLOCK_SIZE * ((message_length + AES_BLOCK_SIZE) / AES_BLOCK_SIZE);
    uint8_t *encrypted = OPENSSL_malloc(encrypted_length);
    EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new();
    CHECK_ONE(EVP_SealInit(cctx, cipher, enc_key, enc_key_length, iv, pubkeys, N_KEYS));
    CHECK_ONE(EVP_SealUpdate(cctx, encrypted, &encrypted_length, message, message_length));
    CHECK_ONE(EVP_SealFinal(cctx, encrypted + encrypted_length, &tmp));
    encrypted_length += tmp;
    EVP_CIPHER_CTX_free(cctx);


    ////////////////////////////////////////////////////////////////////////////
    // DUMP ENCRYPTED KEYS & IV
    for (int i = 0; i < N_KEYS; ++i)
    {
        BIO_printf(bio, "Encrypted Session Key(%d)\n", i + 1);
        BIO_dump(bio, (const char*)enc_key[i], enc_key_length[i]);
    }
    BIO_puts(bio, "IV\n");
    BIO_dump(bio, (const char*)iv, AES_BLOCK_SIZE);


    ////////////////////////////////////////////////////////////////////////////
    // DUMP ENCRYYPTED MESSAGE
    BIO_puts(bio, "Encrypted Message\n");
    BIO_dump(bio, (const char*)encrypted, encrypted_length);


    ////////////////////////////////////////////////////////////////////////////
    // TEST EACH KEY DECRYPTION
    for (int i = 0; i < N_KEYS; ++i)
    {
        char *decrypted = OPENSSL_malloc(encrypted_length);
        int outl = 0, tmp;

        EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
        CHECK_ONE(EVP_OpenInit(ctx, cipher, enc_key[i], enc_key_length[i], iv, keys[i]));
        CHECK_ONE(EVP_OpenUpdate(ctx, decrypted, &outl, encrypted, encrypted_length));
        CHECK_ONE(EVP_OpenFinal(ctx, decrypted + outl, &tmp));
        outl += tmp;

        BIO_printf(bio, "Decrypted Message(%d)\n", i + 1);
        BIO_dump(bio, (const char*)decrypted, outl);

        // cleanup the context and dynamic allocations
        CHECK_ONE(EVP_CIPHER_CTX_cleanup(ctx));
        EVP_CIPHER_CTX_free(ctx);
        OPENSSL_free(decrypted);
    }

    ////////////////////////////////////////////////////////////////////////////
    // TEST SESSION KEY DECRYPTION USING PRIVATE KEYS
    //  (these should all display the same session key)
    for (int i = 0; i < N_KEYS; ++i)
    {
        uint8_t *out = NULL;
        int outl = 0;

        EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(keys[i], NULL);
        CHECK_ONE(EVP_PKEY_decrypt_init(ctx));
        CHECK_ONE(EVP_PKEY_decrypt(ctx, NULL, &outl, enc_key[i], enc_key_length[i]));

        out = OPENSSL_malloc(outl);
        CHECK_ONE(EVP_PKEY_decrypt(ctx, out, &outl, enc_key[i], enc_key_length[i]));

        BIO_printf(bio, "Decrypted Session Key(%d)\n", i + 1);
        BIO_dump(bio, out, outl);

        EVP_PKEY_CTX_free(ctx);
        OPENSSL_free(out);
    }

    ////////////////////////////////////////////////////////////////////////////
    // CLEANUP

    for (int i = 0; i < N_KEYS; ++i)
    {
        OPENSSL_free(enc_key[i]);
        EVP_PKEY_free(pubkeys[i]);
        EVP_PKEY_free(keys[i]);
    }
    OPENSSL_free(encrypted);
    OPENSSL_free(enc_key);
    OPENSSL_free(enc_key_length);
    OPENSSL_free(pubkeys);
    OPENSSL_free(keys);
    BIO_free(bio);

    return EXIT_SUCCESS;
}

示例输出

Encrypted Session Key(1)
0000 - 25 45 c0 22 3b 0c f0 bb-88 a1 a5 fb 18 7b 91 fd   %E.";........{..
0010 - ca 42 ac b8 50 1f a6 3d-13 85 8a 88 01 34 82 c7   .B..P..=.....4..
0020 - 31 18 7f ab 7d 93 d6 3c-e0 0b 6a b6 21 a5 0b f0   1...}..<..j.!...
0030 - 5a 68 31 dc 3a 0c b4 3a-05 9f 95 f4 d6 ae c9 c1   Zh1.:..:........
0040 - cb 20 5c 40 d6 49 7e 38-76 da 89 d4 d9 20 ce 5d   . \@.I~8v.... .]
0050 - 84 93 7e bf 21 72 26 0e-4b 17 f0 30 91 d0 64 88   ..~.!r&.K..0..d.
0060 - 42 93 65 5c df 4b 43 3d-ae 64 a4 b4 65 40 92 a2   B.e\.KC=.d..e@..
0070 - 9f 63 2b 53 19 50 d8 20-24 16 47 ed 3a 0b ff 06   .c+S.P. $.G.:...
0080 - 9b 68 98 6a cb fc ca ca-98 c1 80 7d ac f1 84 67   .h.j.......}...g
0090 - 94 c1 c3 e4 60 9a 59 1b-0f 0e 1d 82 d6 07 99 98   ....`.Y.........
00a0 - c9 34 eb 9a 7c 86 8a f9-1c 9c 5d 4b e8 29 59 30   .4..|.....]K.)Y0
00b0 - 54 0f 6c c3 65 75 63 79-22 94 1e 34 53 89 3a 2f   T.l.eucy"..4S.:/
00c0 - 32 9e a8 31 11 bd c1 c5-ee 70 4c 31 ad 20 a2 ab   2..1.....pL1. ..
00d0 - 55 65 8a f2 94 c3 41 96-8d e9 c6 8f 7a 15 d4 15   Ue....A.....z...
00e0 - de 36 99 3e 0f cd 22 0a-25 cc ca 7d 8c 02 ac c6   .6.>..".%..}....
00f0 - f3 3e 00 c7 e2 4a 8b c7-83 a9 65 d4 ac 6c 46 e6   .>...J....e..lF.
0100 - d3 b9 32 c3 95 26 f8 05-c2 31 ff 89 f6 65 3f df   ..2..&...1...e?.
0110 - 9e 40 94 b5 ca 80 8c ed-f3 00 0a 97 10 79 e5 a6   .@...........y..
0120 - 6b 99 47 c5 7c dd 60 79-9d 7a ad 92 7f 16 ca 0a   k.G.|.`y.z......
0130 - 5c b3 53 2c 21 ea e5 2e-e3 7b 31 42 29 10 cd 30   \.S,!....{1B)..0
0140 - 3e 51 49 07 32 9a f1 c7-f3 2a 59 50 21 7d 02 53   >QI.2....*YP!}.S
0150 - fa 3a 51 d1 23 be fe ab-4f 67 ac a4 41 60 ee fa   .:Q.#...Og..A`..
0160 - b7 e0 1d e7 51 3f 38 99-5f 55 06 3f 54 a9 30 cb   ....Q?8._U.?T.0.
0170 - ea 33 f1 b5 e6 12 cb 21-b1 d0 c7 7d 41 ab 0f d3   .3.....!...}A...
Encrypted Session Key(2)
0000 - 17 87 b4 5a 65 c0 c8 68-47 f2 49 5e ae 8e e0 32   ...Ze..hG.I^...2
0010 - af 97 7b e6 43 c1 39 a0-78 f4 03 2a 0b 9c 35 03   ..{.C.9.x..*..5.
0020 - 36 12 50 69 25 6c 21 62-b6 9b 8a 5a 7b 36 91 93   6.Pi%l!b...Z{6..
0030 - cd d0 99 60 2c 33 bb c5-47 27 c3 15 09 b3 32 1c   ...`,3..G'....2.
0040 - ea 63 5b 8d 33 5b 43 cc-35 55 5d 29 c1 a4 e2 e9   .c[.3[C.5U])....
0050 - eb 4f 03 cd c1 d1 2a b2-f1 28 8c 51 82 8c d6 fd   .O....*..(.Q....
0060 - 5a 08 58 8c ca 24 d7 25-b6 62 dc c1 4e 33 ac 75   Z.X..$.%.b..N3.u
0070 - be f9 10 8e 40 e7 bd 9b-d3 38 2d f9 08 70 3a 71   ....@....8-..p:q
0080 - df 6b f7 68 7e 6e 23 f9-fc bf 6c 65 fc 5b 05 bf   .k.h~n#...le.[..
0090 - 17 4b ff 10 08 6e 07 78-3b 14 2e 1f 85 a4 a2 b8   .K...n.x;.......
00a0 - f4 7c 05 d6 5b 73 ae 54-11 07 97 62 4e a5 66 8f   .|..[s.T...bN.f.
00b0 - 71 72 71 8d 1d b4 e4 52-32 7c 07 68 e7 73 19 7f   qrq....R2|.h.s..
00c0 - 40 ae 9f 7b 3c 5d 5d 69-77 9d a2 5c ee 83 08 f1   @..{<]]iw..\....
00d0 - c6 67 05 62 78 7a 00 73-c9 ca 50 26 52 27 31 e0   .g.bxz.s..P&R'1.
00e0 - dd 03 5e db 59 29 51 ff-85 d6 17 d4 fe e9 7c b1   ..^.Y)Q.......|.
00f0 - d6 d6 8a 33 df df 0a 15-40 4c 92 45 4a 98 5d 78   ...3....@L.EJ.]x
0100 - 05 e8 c3 df 50 29 c7 3c-ed 56 ca 64 c7 8b 1f 86   ....P).<.V.d....
0110 - 5b b0 c8 52 bb aa 2b 98-02 5e 99 52 b3 59 fd 33   [..R..+..^.R.Y.3
0120 - 36 f5 9b e5 ec 00 b0 0b-33 74 ed 80 10 b3 fd f1   6.......3t......
0130 - 7b 3f 83 8a 94 28 4e e8-14 a6 2d fa d9 c9 01 46   {?...(N...-....F
0140 - 23 a6 85 93 4d 34 12 8d-e1 a4 76 a3 ea 2e 15 0b   #...M4....v.....
0150 - 00 b6 b3 b9 3a 09 4f d8-a3 47 a4 45 9d ff 64 0a   ....:.O..G.E..d.
0160 - 15 21 4e d9 65 db ce 1f-b6 35 c0 43 f9 5b f0 d7   .!N.e....5.C.[..
0170 - f6 c0 5d 01 43 1c aa 0f-bd ee 9a 0b cc 10 f0 c9   ..].C...........
Encrypted Session Key(3)
0000 - 12 fc 55 62 93 32 2a 27-a6 45 d3 fc 63 b6 d4 0b   ..Ub.2*'.E..c...
0010 - 30 37 28 56 03 9f 3e 06-1a 24 0f 97 c4 f4 89 b0   07(V..>..$......
0020 - ab e2 16 90 19 fd fc 7e-8f e3 3a 58 f6 20 04 a2   .......~..:X. ..
0030 - 47 c8 f6 40 c0 9b b3 d6-0c 6f 56 72 4c 57 5d 19   G..@.....oVrLW].
0040 - d1 04 5e d6 63 dc e1 4d-b8 0b 36 19 8a e0 4e 2e   ..^.c..M..6...N.
0050 - 67 7a de c5 31 cc 50 44-19 54 1f a7 9a 03 78 27   gz..1.PD.T....x'
0060 - 69 82 b7 ef 0e d4 55 42-3e 32 9a ef 76 90 5b 76   i.....UB>2..v.[v
0070 - d3 e7 17 5d 23 ca 49 54-d1 5e 67 3a b3 90 0f 0c   ...]#.IT.^g:....
0080 - 30 55 04 e6 a8 dd 19 9c-34 c2 4e 9f 76 9a b8 1b   0U......4.N.v...
0090 - 18 e5 e7 8d aa b0 51 b9-aa 1b 15 92 a8 a4 05 fe   ......Q.........
00a0 - fd b3 90 d9 bb 7a 06 d8-22 32 dd 3e ed 78 eb 17   .....z.."2.>.x..
00b0 - cc 66 52 20 e6 ae 8f a6-66 54 12 0a 14 cd 9a 88   .fR ....fT......
00c0 - 05 84 27 17 79 49 df da-a2 79 47 0c 2b d5 50 7b   ..'.yI...yG.+.P{
00d0 - 89 22 34 40 ac f7 89 3a-f8 71 46 ec d7 45 9a 31   ."4@...:.qF..E.1
00e0 - e2 d4 47 49 1e ef af 19-4e 8c 1a a3 90 08 0b 8a   ..GI....N.......
00f0 - 81 16 bb 18 2d 93 4a 3e-ad 72 a6 ab 35 dd a5 fc   ....-.J>.r..5...
0100 - 94 48 39 88 18 37 71 43-ab 47 20 e1 fd 52 65 52   .H9..7qC.G ..ReR
0110 - fc b4 83 23 94 7f db 5c-51 66 e4 01 45 18 8a 78   ...#...\Qf..E..x
0120 - 49 48 d0 0b 05 54 5b 0c-58 eb b5 bb c2 40 b0 80   IH...T[.X....@..
0130 - 8f 86 23 b5 61 7d be 44-45 02 e5 ab 7b 41 80 cb   ..#.a}.DE...{A..
0140 - 81 99 23 48 d5 70 d6 97-b4 96 3d 72 db ef 9d d2   ..#H.p....=r....
0150 - 3e e6 09 a4 e3 d4 91 17-42 42 f6 e6 27 06 9e 2f   >.......BB..'../
0160 - 8e 02 31 50 da ef 66 96-8a e6 5c 7e 0f fc 00 49   ..1P..f...\~...I
0170 - b3 5d 89 27 98 15 ad 9f-2a 1d 9f 5e 2f db ba a3   .].'....*..^/...
IV
0000 - b4 27 52 75 a0 46 77 07-ff 29 ff 5e 77 c8 66 be   .'Ru.Fw..).^w.f.
Encrypted Message
0000 - ba a5 36 53 1a 69 07 71-04 87 b6 88 6b 9f 38 4a   ..6S.i.q....k.8J
0010 - 9c 1a 9a 3b c9 76 1c ca-d5 78 3c 42 91 a1 30 56   ...;.v...x<B..0V
0020 - 3f 4f 0a 55 64 7e 05 c1-6a 05 3d bd 92 ec 5d 03   ?O.Ud~..j.=...].
Decrypted Message(1)
0000 - 54 68 65 20 71 75 69 63-6b 20 62 72 6f 77 6e 20   The quick brown
0010 - 66 6f 78 20 6a 75 6d 70-73 20 6f 76 65 72 20 74   fox jumps over t
0020 - 68 65 20 6c 61 7a 79 20-64 6f 67 2e               he lazy dog.
Decrypted Message(2)
0000 - 54 68 65 20 71 75 69 63-6b 20 62 72 6f 77 6e 20   The quick brown
0010 - 66 6f 78 20 6a 75 6d 70-73 20 6f 76 65 72 20 74   fox jumps over t
0020 - 68 65 20 6c 61 7a 79 20-64 6f 67 2e               he lazy dog.
Decrypted Message(3)
0000 - 54 68 65 20 71 75 69 63-6b 20 62 72 6f 77 6e 20   The quick brown
0010 - 66 6f 78 20 6a 75 6d 70-73 20 6f 76 65 72 20 74   fox jumps over t
0020 - 68 65 20 6c 61 7a 79 20-64 6f 67 2e               he lazy dog.
Decrypted Session Key(1)
0000 - 31 06 13 9d a3 11 dd ab-c1 e4 cb f4 fc d5 3f 60   1.............?`
0010 - 36 42 55 d2 38 bc c9 82-11 ac 1e 61 3a 94 2c 7f   6BU.8......a:.,.
Decrypted Session Key(2)
0000 - 31 06 13 9d a3 11 dd ab-c1 e4 cb f4 fc d5 3f 60   1.............?`
0010 - 36 42 55 d2 38 bc c9 82-11 ac 1e 61 3a 94 2c 7f   6BU.8......a:.,.
Decrypted Session Key(3)
0000 - 31 06 13 9d a3 11 dd ab-c1 e4 cb f4 fc d5 3f 60   1.............?`
0010 - 36 42 55 d2 38 bc c9 82-11 ac 1e 61 3a 94 2c 7f   6BU.8......a:.,.