Hi,
I want to generate a RSA private and public key and than encrypt the
private key symmetrically with a password to store it on a server. The
data has to be stored and transferred base64 encoded.
This is how I encrypt the private key:
EVP_CIPHER_CTX ctx;
unsigned char *key = (unsigned char*)password.toLocal8Bit().data();
unsigned char *data = (unsigned char*)privkey.toLocal8Bit().constData());
int len = strlen((char*)data)+1;
unsigned char iv[EVP_MAX_IV_LENGTH];
select_random_iv(iv, EVP_MAX_IV_LENGTH);
int c_len = len + AES_BLOCK_SIZE, f_len = 0;
unsigned char *ciphertext = (unsigned char*)malloc(c_len);
EVP_EncryptInit(&ctx, EVP_aes_128_cfb(), key, iv);
EVP_EncryptUpdate(&ctx, ciphertext, &c_len, data, len);
EVP_EncryptFinal(&ctx, ciphertext+c_len, &f_len);
This works fine and if I send the encrypted data, the iv, the key and
the password directly to the decrypt function (decryptPrivateKey(...))
I can also decrypt the data again. But if I encode the data together
with the iv as base64 to store it on the server and later decode it
again the decryption fails.
Here is how I encode the data together with the iv in base64:
char *base64Key = base64(ciphertext, strlen((char*)ciphertext));
char *base64IV = base64(iv, strlen((char*)iv));
char *iv_seperator = (char*)"00iv00";
base64Key = (char*)realloc(base64Key,
strlen(base64Key)+strlen(base64IV)+6+1);
strcat(base64Key, iv_seperator);
strcat(base64Key, base64IV);
The result is a string <data>"00iv00"<iv> which I transfer to the
server. Now when I retrieve the data again I separate the encrypted key
and the iv, decode it and send it to the decryption function:
char *data = privkey.toLocal8Bit().data();
char keyBase64[strlen(data)+1];
char ivBase64[2000];
int separator, i;
bool isKey = true;
for(i = 0; i<strlen(data); i++) {
if (data[i] == '0' && data[i+1] == '0' && data[i+2] == 'i' && data[i+3]
== 'v' && data[i+4] == '0' && data[i+5] == '0') {
isKey = false;
keyBase64[i] = '\0';
i += 5;
separator = i;
} else {
if (isKey) keyBase64[i] = data[i];
else ivBase64[i-separator-1] = data[i];
}
}
ivBase64[i-separator-1] = '\0';
unsigned char *key = unbase64(keyBase64, strlen(keyBase64));
unsigned char *iv = unbase64(ivBase64, strlen(ivBase64));
return (decryptPrivateKey(key, iv, password));
This is how base64 and unbase64 looks:
char* Encryption::base64(const unsigned char *input, int length)
{
BIO *bmem, *b64;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
char *buff = (char *)malloc(bptr->length+1);
memcpy(buff, bptr->data, bptr->length);
buff[bptr->length] = 0;
BIO_free_all(b64);
return buff;
}
unsigned char* Encryption::unbase64(char *input, int length)
{
BIO *b64, *bmem;
unsigned char *buffer = (unsigned char *)malloc(length);
memset(buffer, 0, length);
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new_mem_buf(input, length);
bmem = BIO_push(b64, bmem);
BIO_read(bmem, buffer, length);
BIO_free_all(bmem);
return buffer;
}
I already tried several other methods to endoce/decode base64 but
nothing really works. Maybe someone on this list can help me?
Thanks a lot!
Björn
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [email protected]
Automated List Manager [email protected]