Re: Convert symmetrically encrypted content to base64

2012-08-27 Thread Bjoern Schiessle
On Fri, 24 Aug 2012 15:54:50 -0400 Dave Thompson wrote:
 Note OpenSSL's RSA privatekey *includes* publickey.
 RSA publickey is n,e and naive privatekey is n,d, 
 but OpenSSL privatekey is CRT form with n,d,e,p,q + more.
 There is no need to transmit the publickey separately, 
  
  [..]
 

 Tiny aside: BIO_new_mem_buf will do the strlen() for you 
 if you pass -1 for length. Just a convenience.
 
 [..]

 If PEM_read_* returns null (or nearly any other OpenSSL 
 routine returns a failure indication), look at the error queue.
 http://www.openssl.org/support/faq.html#PROG6
 and #PROG7 also if you don't get readable error.
 
 If they didn't, look very carefully at your PEM data. 
 Commandline can do this: openssl asn1parse -in myprivkey.pem 
 and/or: openssal rsa -in myprivkey.pem -text


Thanks for your hints. After a lot of testing I figured out
that my functions pem2key() and key2pem() works fine. The problem is
that I lose some characters (e.g. '+' gets replaced by spaces) while
sending the key over the network. But I think this problem don't belong
to the mailing list. ;-)

Thanks a lot!
Björn


-- 
Björn Schießle bjo...@schiessle.org
www: http://schiessle.org 
gnupg key: 0x0x2378A753E2BF04F6 
fingerprint: 244F CEB0 CB09 9524 B21F B896 2378 A753 E2BF 04F6
__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org


Re: Convert symmetrically encrypted content to base64

2012-08-24 Thread Bjoern Schiessle
Hi Christian,

On Fri, 24 Aug 2012 08:11:25 +0200 Christian Hohnstaedt wrote:
 please see my comments below:
 (rather Qt and memory related)

Thank you for your feedback. Now I'm trying the implement the function
which does exactly the opposite: Take the public and private key in
the PEM format from the server and import it in a RSA structure:

void Encryption::pem2key(QString publickey, QString privatekey, QString 
password)
{
BIO *pubBio = BIO_new_mem_buf(publickey.toLocal8Bit().data(), 
strlen(publickey.toLocal8Bit().data()));
BIO *privBio =  BIO_new_mem_buf(privatekey.toLocal8Bit().data(), 
strlen(privatekey.toLocal8Bit().data()));
RSA *rsa = RSA_new();

PEM_read_bio_RSAPublicKey(pubBio, rsa, 0, NULL);
PEM_read_bio_RSAPrivateKey(privBio, rsa, 0, password.toLocal8Bit().data());

Keymanager::Instance()-setRSAkey(rsa);

BIO_free_all(pubBio);
BIO_free_all(privBio);
}


The program compiles and run without a problem. But if I call the
key2pem() function with the newly imported RSA key. I get two quite
short keys back (only half a line of data). So something seems to go
wrong during import of the PEM encoded keys.

Any idea what I'm doing wrong in the pem2key() function?

Thanks!
Björn

__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org


Convert symmetrically encrypted content to base64

2012-08-23 Thread Bjoern Schiessle
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 data00iv00iv 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; istrlen(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 Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org


Re: Convert symmetrically encrypted content to base64

2012-08-23 Thread Bjoern Schiessle
Hi,

I think I did it way too complicated. I think the problem was that I
always tried to mimic some openssl php code I know, but I think the
solution I have now is much easier and standard complained:

void Encryption::generateUserKeys(QString password)
{
RSA *rsa;
EVP_PKEY *pkey;

int bits = 1024;
unsigned long exp = RSA_F4;
QMapQString, QString keypair;

rsa = RSA_generate_key(bits, exp, NULL, NULL);

pkey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey, rsa);

keypair = key2pem(rsa, password);

RSA_free(rsa);

sendUserKeysToServer(keypair);
}

QMapQString, QString Encryption::key2pem(RSA *rsa, QString password)
{
QMapQString, QString keypair;
BUF_MEM *bptr;
BIO *pubBio = BIO_new(BIO_s_mem());
BIO *privBio = BIO_new(BIO_s_mem());

PEM_write_bio_RSA_PUBKEY(pubBio, rsa);
PEM_write_bio_RSAPrivateKey(privBio, rsa, EVP_aes_128_cfb(),NULL,
0, 0, password.toLocal8Bit().data());

BIO_get_mem_ptr(pubBio, bptr);
char *pubKey = (char *)malloc(bptr-length+1);
memcpy(pubKey, bptr-data, bptr-length);
pubKey[bptr-length] = 0;

BIO_get_mem_ptr(privBio, bptr);
char *privKey = (char *)malloc(bptr-length+1);
memcpy(privKey, bptr-data, bptr-length);
privKey[bptr-length] = 0;

keypair[privatekey] = QString(privKey);
keypair[publickey] = QString(pubKey);

BIO_free_all(pubBio);
BIO_free_all(privBio);

return keypair;

}

Please feel free to commend on it if you think there is still something
to improve.

best wishes,
Björn

-- 
Björn Schießle bjo...@schiessle.org
www: http://schiessle.org 
gnupg key: 0x0x2378A753E2BF04F6 
fingerprint: 244F CEB0 CB09 9524 B21F B896 2378 A753 E2BF 04F6
__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org