I'm using openssl trying to use an RSA public key, to encrypt an AES key, and use that AES to send large-ish data over HTTP(s) to a 3rd party site. I know that's a lot of encryption, the second layer comes when the network is down, and the data has to be cached on disk until it can be POST
ed.
我正在使用openssl尝试使用RSA公钥加密AES密钥,并使用该公钥通过HTTP(s)向第三方站点发送大数据。我知道这需要大量的加密,当网络关闭时,第二层就会出现,数据必须被缓存到磁盘上,直到可以发布为止。
I've been using the example code from this blog, a chunk of which is inlined below:
我一直在使用这个博客的示例代码,其中一段代码如下所示:
int aes_init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx)
{
int i, nrounds = 5;
unsigned char key[32], iv[32];
/*
* Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material.
* nrounds is the number of times the we hash the material. More rounds are more secure but
* slower.
*/
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv);
if (i != 32) {
printf("Key size is %d bits - should be 256 bits\n", i);
return -1;
}
for(int x = 0; x<32; ++x)
printf("Key: %x iv: %x \n", key[x], iv[x]);
for(int x = 0; x<8; ++x)
printf("salt: %x\n", salt[x]);
EVP_CIPHER_CTX_init(e_ctx);
EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
return 0;
}
I'd like to stick with his aes_init()
function, but I can't find a way to get the key out of the EVP_CIPHER_CTX
once it has been initialised.
我希望继续使用他的aes_init()函数,但是一旦EVP_CIPHER_CTX被初始化,我就无法找到从它获取密钥的方法。
apropos
lists a few functions relating to EVP_CIPHER_CTX
:
列出了与EVP_CIPHER_CTX相关的几个函数:
$ apropos EVP_CIPHER_CTX
EVP_CIPHER_CTX_block_size (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_cipher (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_cleanup (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_ctrl (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_flags (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_get_app_data (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_init (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_iv_length (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_key_length (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_mode (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_nid (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_set_app_data (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_set_key_length (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_set_padding (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_type (3ssl) - EVP cipher routines
EVP_CIPHER_CTX_set_key_length
looks promising, but is there then some magical offset from which I have to read the EVP_CIPHER_CTX
? Otherwise, I'll have to modify his function to return the key
(and the iv
), or throw away the function and inline the code.
EVP_CIPHER_CTX_set_key_length看起来很有希望,但是是否有一些不可思议的偏移量,我必须读取EVP_CIPHER_CTX?否则,我将不得不修改他的函数来返回键(和iv),或者丢弃函数并内联代码。
The end goal here is to encrypt a large portion of data using AES, and encrypt the AES key using our RSA public key, base64 encode both, and broadcast them to the server. (Which I believe is the correct way of doing things)
这里的最终目标是使用AES加密大部分数据,并使用我们的RSA公钥(base64对两者进行编码)加密AES密钥,并将其广播到服务器。(我相信这是正确的做事方式)
The only issue then, is extracting the key from the EVP_CIPHER_CTX
.
那么,惟一的问题就是从EVP_CIPHER_CTX中提取密钥。
1 个解决方案
#1
2
Why would you want to build your own solution to this kind of hybrid cryptography? There are already existing standards and methods that can help you.
为什么要为这种混合密码学构建自己的解决方案呢?已有一些标准和方法可以帮助您。
I recommend you look into the PKCS#7 standard, which is the basis for S/MIME. OpenSSL has a direct interface to it. You tell it which data you want to encrypt using an asymmetric key and it handles the rest for you.
我建议您研究一下PKCS#7标准,它是S/MIME的基础。OpenSSL有一个直接的接口。您告诉它使用非对称密钥加密哪些数据,它将为您处理其余的数据。
Look at pkcs7_encrypt
and pkcs7_decrypt
as well as the i2d_PKCS7_*
functions for how to extract that data into a transmittable format (and d2i_PKCS7_*
for reverse). See OpenSSL's documentation: PKCS7_encrypt, PKCS7_decrypt and you might want to familiarize yourself with the i2d/d2i convention used by OpenSSL (this is X509 but the d2i part applies here as well.
看看pkcs7_encrypt pkcs7_decrypt以及i2d_PKCS7_ *函数如何提取数据到剧增格式(反向和d2i_PKCS7_ *)。看到OpenSSL文档:PKCS7_encrypt PKCS7_decrypt,您可能想要熟悉i2d / d2i公约所使用OpenSSL(这是X509但d2i部分在这里也同样适用。
Edit: Here is an example for encryption (decryption is analogous):
编辑:这里有一个加密的例子(解密类似):
#include <stdio.h>
#include <openssl/pem.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
int main()
{
STACK_OF(X509) *certs;
FILE *fp;
BIO *bio;
PKCS7 *p7;
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
certs = sk_X509_new_null();
fp = fopen("cert.pem", "r");
sk_X509_push(certs, PEM_read_X509(fp, NULL, NULL, NULL));
fclose(fp);
bio = BIO_new_file("data.txt", "r");
p7 = PKCS7_encrypt(certs, bio, EVP_des_ede3_cbc(), 0);
BIO_free(bio);
bio = BIO_new_file("data.txt.enc", "w");
i2d_PKCS7_bio(bio, p7);
BIO_flush(bio);
BIO_free(bio);
ERR_print_errors_fp(stdout);
return 0;
}
I have uploaded the full example to my repository.
我已经将完整的示例上载到我的存储库中。
#1
2
Why would you want to build your own solution to this kind of hybrid cryptography? There are already existing standards and methods that can help you.
为什么要为这种混合密码学构建自己的解决方案呢?已有一些标准和方法可以帮助您。
I recommend you look into the PKCS#7 standard, which is the basis for S/MIME. OpenSSL has a direct interface to it. You tell it which data you want to encrypt using an asymmetric key and it handles the rest for you.
我建议您研究一下PKCS#7标准,它是S/MIME的基础。OpenSSL有一个直接的接口。您告诉它使用非对称密钥加密哪些数据,它将为您处理其余的数据。
Look at pkcs7_encrypt
and pkcs7_decrypt
as well as the i2d_PKCS7_*
functions for how to extract that data into a transmittable format (and d2i_PKCS7_*
for reverse). See OpenSSL's documentation: PKCS7_encrypt, PKCS7_decrypt and you might want to familiarize yourself with the i2d/d2i convention used by OpenSSL (this is X509 but the d2i part applies here as well.
看看pkcs7_encrypt pkcs7_decrypt以及i2d_PKCS7_ *函数如何提取数据到剧增格式(反向和d2i_PKCS7_ *)。看到OpenSSL文档:PKCS7_encrypt PKCS7_decrypt,您可能想要熟悉i2d / d2i公约所使用OpenSSL(这是X509但d2i部分在这里也同样适用。
Edit: Here is an example for encryption (decryption is analogous):
编辑:这里有一个加密的例子(解密类似):
#include <stdio.h>
#include <openssl/pem.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
int main()
{
STACK_OF(X509) *certs;
FILE *fp;
BIO *bio;
PKCS7 *p7;
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
certs = sk_X509_new_null();
fp = fopen("cert.pem", "r");
sk_X509_push(certs, PEM_read_X509(fp, NULL, NULL, NULL));
fclose(fp);
bio = BIO_new_file("data.txt", "r");
p7 = PKCS7_encrypt(certs, bio, EVP_des_ede3_cbc(), 0);
BIO_free(bio);
bio = BIO_new_file("data.txt.enc", "w");
i2d_PKCS7_bio(bio, p7);
BIO_flush(bio);
BIO_free(bio);
ERR_print_errors_fp(stdout);
return 0;
}
I have uploaded the full example to my repository.
我已经将完整的示例上载到我的存储库中。