我正在尝试为密钥信封实施hybrid cryptosystem( RSA ,并为数据信封实施 DES3(带双键选项))。因此,我首先尝试使用Openssl的EVP
函数实现DES3。因为我似乎可以轻松地使用EVP来组合RSA和DES3加密。
我从Openssl书中获得了这个示例代码(更改数据类型以修复gcc警告并将代码段放在一个文件中):
#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
unsigned char *encrypt_example(EVP_CIPHER_CTX *ctx, unsigned char *data, int inl, int *rb);
unsigned char *decrypt_example(EVP_CIPHER_CTX *ctx, unsigned char *ct, int inl);
void select_random_key(unsigned char *key, int b);
void select_random_iv(unsigned char *iv, int b);
int seed_prng(int bytes);
int main(int argc, char *argv[])
{
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
unsigned char key[EVP_MAX_KEY_LENGTH];
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char *ct, *out;
unsigned char final[EVP_MAX_BLOCK_LENGTH];
unsigned char str[] = "123456789abcdef";
int i = 0;
if (!seed_prng(16))
{
printf("Fatal Error! Unable to seed the PRNG!\n");
abort();
}
select_random_key(key, EVP_MAX_KEY_LENGTH);
select_random_iv(iv, EVP_MAX_IV_LENGTH);
/* EVP_des_ede3() :three-key DES3 with ECB
* EVP_des_ede() :two-key DES3 with ECB
* EVP_des_ede_cbc() :two-key DES3 with CBC
* EVP_des_ede3_cbc() :three-key DES3 with CBC */
EVP_EncryptInit(&ctx, EVP_des_ede_cbc(), key, NULL);
ct = encrypt_example(&ctx, str, strlen((const char*)str), &i);
printf("Ciphertext is %d bytes.\n", i);
EVP_DecryptInit(&ctx, EVP_des_ede_cbc(), key, NULL);
out = decrypt_example(&ctx, ct, 8);
printf("Decrypted: >>%s<<\n", out);
out = decrypt_example(&ctx, ct + 8, 8);
printf("Decrypted: >>%s<<\n", out);
if (!EVP_DecryptFinal(&ctx, final, &i))
{
printf("Padding incorrect.\n");
abort();
}
final[i] = 0;
printf("Decrypted: >>%s<<\n", final);
return 0;
}
int seed_prng(int bytes)
{
if (!RAND_load_file("/dev/random", bytes))
return 0;
return 1;
}
void select_random_key(unsigned char *key, int b)
{
int i;
RAND_bytes(key, b);
for (i = 0; i < b - 1; i++)
printf("%02X:",key[i]);
printf("%02X\n\n", key[b - 1]);
}
void select_random_iv (unsigned char *iv, int b)
{
RAND_pseudo_bytes (iv, b);
}
unsigned char *encrypt_example(EVP_CIPHER_CTX *ctx, unsigned char *data, int inl, int *rb)
{
unsigned char *ret = (unsigned char *)malloc(inl + EVP_CIPHER_CTX_block_size(ctx));
int i, tmp, ol;
ol = 0;
for (i = 0; i < inl /100; i++)
{
EVP_EncryptUpdate(ctx, &ret[ol], &tmp, &data[ol], 100);
ol += tmp;
}
if (inl % 100)
{
EVP_EncryptUpdate(ctx, &ret[ol], &tmp, &data[ol], inl%100);
ol += tmp;
}
EVP_EncryptFinal(ctx, &ret[ol], &tmp);
*rb = ol + tmp;
return ret;
}
unsigned char *decrypt_example(EVP_CIPHER_CTX *ctx, unsigned char *ct, int inl)
{
/* We're going to null-terminate the plaintext under the assumption it's
* non-null terminated ASCII text. The null can be ignored otherwise.
*/
unsigned char *pt = (unsigned char *)malloc(inl + EVP_CIPHER_CTX_block_size(ctx) + 1);
int ol;
EVP_DecryptUpdate(ctx, pt, &ol, ct, inl);
if (!ol) /* there's no block to decrypt */
{
free(pt);
return NULL;
}
pt[ol] = 0;
return pt;
}
我正在用这个
编译它gcc -g -O0 -Wall evp_encrypt_decrypt.c -o evp_encrypt_decrypt -lssl -lcrypto
现在,如果我执行此操作,我会得到此输出:
13:98:EB:64:D5:8B:1E:0A:70:1D:28:9D:25:3A:13:40:FE:C1:81:3C:C5:8F:4B:F6:66:1A:07:F8:17:D6:10:B6:4E:BC:45:96:00:A1:9F:59:44:A0:43:D9:9D:DD:C8:A9:0B:22:EC:7B:F2:5F:78:01:D1:58:6D:0B:B4:CB:5F:CD
Ciphertext is 16 bytes.
Decrypted: >>(null)<<
Decrypted: >>12345678<<
Decrypted: >>9abcdef<<
这里说的是chipertext是16个字节(没关系)。但是密钥本身(上面打印的十六进制代码) 64字节长!
但是,具有双键选项的DES3应具有128位的密钥长度(包括奇偶校验位)。但是, EVP_MAX_KEY_LENGTH 定义默认为 64 。另外,我试图打印chiper密钥长度,变量key
的大小和ctx密钥大小,如下所示:
printf("Key length DES3: %d\n", EVP_CIPHER_key_length(EVP_des_ede3_cbc()));
printf("Key size: %d\n", sizeof(key));
printf("Cipher CTX key length: %d\n\n", EVP_CIPHER_CTX_key_length(&ctx));
这将输出:
Key length DES3: 24
Key size: 64
Cipher CTX key length: 16
我在这里有点困惑。不应该是DES3(双键)密钥大小128位?为什么DES3键的长度打印为24(是这个位,字节等)?为什么所有这些关键长度和尺寸都不同?
答案 0 :(得分:0)
但是,具有双键选项的DES3应具有128位的密钥长度(包括奇偶校验位)
是。 2键3DES的密钥大小为64x2 = 128位;和3键3DES的密钥大小为64x3 = 192位(如Greg S所述)。
然而,EVP_MAX_KEY_LENGTH定义默认为64
它可以达到的最大值(对于所有EVP对称密码),而不仅仅是DES / 3DES / AES等。该值甚至可能在将来发生变化。
不应该是DES3(双键)密钥大小为128位吗?
是
为什么DES3键的长度打印为24(此位,字节等)?
谁知道....但它的字节数,而不是位数。
为什么所有这些关键长度和大小都不同?
大小基于算法或密码系统。
2键3DES执行Encrypt-Decrypt-Encrypt并使用两个键。因此,其中一个键使用了两次。 3键3DES执行Encrypt-Decrypt-Encrypt并使用三个独立的键。那是他们的设计方式。