Aes encryption compatible with openssl cmd
-
Hi,
@Marek said in Aes encryption compatible with openssl cmd:
QString arg("letmein");
int len = arg.toLocal8Bit().length()+1;
auto plainText = reinterpret_cast<unsigned char*>(const_cast<char*>(static_cast<const char*>(arg.toLatin1())));Why are you using two different encoding ?
plainText does not point what you think. The toLatin1 method returns a QByteArray, not a char pointer.
-
Hi,
@Marek said in Aes encryption compatible with openssl cmd:
QString arg("letmein");
int len = arg.toLocal8Bit().length()+1;
auto plainText = reinterpret_cast<unsigned char*>(const_cast<char*>(static_cast<const char*>(arg.toLatin1())));Why are you using two different encoding ?
plainText does not point what you think. The toLatin1 method returns a QByteArray, not a char pointer.
@SGaist Hi
I took this example from forum https://forum.qt.io/topic/96587/qt-with-openssl-aes-256-cbc-encryption/4when I change this line to:
unsigned char* plainText=reinterpret_cast<unsigned char *>(arg.toLocal8Bit().data()); OR unsigned char plainText[]="letmein";
Output is the same as previous
BEGIN openssl2 EncryptMgr::openssl2 ciphertext: "f602bdec9c84c0d3476ebf6115588131" base: "9gK97JyEwNNHbr9hFViBMQ==" EncryptMgr::openssl2 decryptText: "letmein" END openssl2
Here I'm testing all known (to me) combination of openssl enc cmd
enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 IAa9TSIdLCIU7XRDiHemxg== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 Uxj0FgyEY3Bc1XDaaoIsTw== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 -md md5 fdDcCauSOiGYGNmUPnFaLg== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 -md md5 wa5TR/Vbe3spT7RhVKxX3Q== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 -md sha1 HFL8j/EPy/Q5NGoy5Ujkcw== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 -md sha1 iwY4XIcGLATKRyyP+n377w== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 9Mjk39/gvgO42P3nuVzKHg== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md md5 J5bUApllT5MCB2hAukm9Zw== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md sha1 1mt3AKZ9fpLCgLIlPIOkHA== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 Bd6B3CUO0nn6thX+Cs3nWw== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 jl4vRGtTxItse8xHf4vygQ== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 -md md5 tCFPTf5AkS34DOkPcPK6aQ== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 -md md5 I0r5J3ZnlctvH9bjphaDQg== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 -md sha1 tWpHRO2gyhkIj04fx8f51A== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 -md sha1 eWHrPFxtOcbN3eVy2eUzOA== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 zkcvwZ+6q8NEmS4my2TFJQ== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md md5 tZzIRZ7crQ38LDLYxyz3tA== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md sha1 iZ5IdMK9pkAg0HRF38mHNQ== enc_test$
complete madness ;)
Best,
Marek -
@SGaist Hi
I took this example from forum https://forum.qt.io/topic/96587/qt-with-openssl-aes-256-cbc-encryption/4when I change this line to:
unsigned char* plainText=reinterpret_cast<unsigned char *>(arg.toLocal8Bit().data()); OR unsigned char plainText[]="letmein";
Output is the same as previous
BEGIN openssl2 EncryptMgr::openssl2 ciphertext: "f602bdec9c84c0d3476ebf6115588131" base: "9gK97JyEwNNHbr9hFViBMQ==" EncryptMgr::openssl2 decryptText: "letmein" END openssl2
Here I'm testing all known (to me) combination of openssl enc cmd
enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 IAa9TSIdLCIU7XRDiHemxg== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 Uxj0FgyEY3Bc1XDaaoIsTw== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 -md md5 fdDcCauSOiGYGNmUPnFaLg== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 -md md5 wa5TR/Vbe3spT7RhVKxX3Q== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 -md sha1 HFL8j/EPy/Q5NGoy5Ujkcw== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 -md sha1 iwY4XIcGLATKRyyP+n377w== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 9Mjk39/gvgO42P3nuVzKHg== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md md5 J5bUApllT5MCB2hAukm9Zw== enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md sha1 1mt3AKZ9fpLCgLIlPIOkHA== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 Bd6B3CUO0nn6thX+Cs3nWw== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 jl4vRGtTxItse8xHf4vygQ== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 -md md5 tCFPTf5AkS34DOkPcPK6aQ== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 -md md5 I0r5J3ZnlctvH9bjphaDQg== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 1 -md sha1 tWpHRO2gyhkIj04fx8f51A== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 -md sha1 eWHrPFxtOcbN3eVy2eUzOA== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 zkcvwZ+6q8NEmS4my2TFJQ== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md md5 tZzIRZ7crQ38LDLYxyz3tA== enc_test$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md sha1 iZ5IdMK9pkAg0HRF38mHNQ== enc_test$
complete madness ;)
Best,
Marek@Marek said in Aes encryption compatible with openssl cmd:
arg.toLocal8Bit().data()
You've working on a temporary. Basic c++ error.
-
@Marek said in Aes encryption compatible with openssl cmd:
unsigned char* plainText=reinterpret_cast<unsigned char *>(arg.toLocal8Bit().data());
You are taking the data pointer of a temporary QByteArray which lifetime ends after the semi colon therefore pointing to somewhere that may or may not contain the data.
You have to ensure that the lifetime of your objects.
As already written numerous time:
QString someString("Foo bar"); QByteArray latin1Array = someString.toLatin1(); // Now you can use your pointer thingy based on latin1Array.data()
-
@Marek said in Aes encryption compatible with openssl cmd:
unsigned char* plainText=reinterpret_cast<unsigned char *>(arg.toLocal8Bit().data());
You are taking the data pointer of a temporary QByteArray which lifetime ends after the semi colon therefore pointing to somewhere that may or may not contain the data.
You have to ensure that the lifetime of your objects.
As already written numerous time:
QString someString("Foo bar"); QByteArray latin1Array = someString.toLatin1(); // Now you can use your pointer thingy based on latin1Array.data()
@SGaist @Christian-Ehrlicher thanks for your help
but no difference
QString arg("letmein"); QByteArray latin1Array = arg.toLatin1(); unsigned char* plainText=reinterpret_cast<unsigned char *>(latin1Array.data());
Result is the same:
BEGIN openssl2 EncryptMgr::openssl2 ciphertext: "f602bdec9c84c0d3476ebf6115588131" base: "9gK97JyEwNNHbr9hFViBMQ==" EncryptMgr::openssl2 decryptText: "letmein" END openssl2
And I even tested just hardcoding string letmein as unsinged char (same result)
unsigned char plainText[]="letmein"
But maybe there is some error with reading cipher text from unsigned char to QByteArray ?
Best
Marek -
There is so much code which is not needed so I don't understand what's really going on. For such a simple encryption not more than 10 lines should be needed. Please provide a minimal compilable example.
And are you sure the\0
is added on command line? I would guess no. -
There is so much code which is not needed so I don't understand what's really going on. For such a simple encryption not more than 10 lines should be needed. Please provide a minimal compilable example.
And are you sure the\0
is added on command line? I would guess no.@Christian-Ehrlicher
There are three types of encrypt/decrypt atempts in this code thats why it looks big,
I can't shrink it unless I remove one of methods-
openssl2 function is using:
aes_init - to init openssl and EVP_BytesToKey to create key from password
aes_encrypt - to encypt
aes_decrypt - to decrypt
openssl2 is initializing aes, performs encrypt and decrypt and prints the result -
openssl function is using:
encrypt - to encrypt
decrypt - to decrypt
handleErrors - doesn't matter
This one is different in terms of key handling, does not derive key from password, key is already provided, taken from openssl command
openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md sha1 -p
- This is just using https://github.com/bricke/Qt-AES
all in single procedure
Best,
Marek -
-
@Christian-Ehrlicher
There are three types of encrypt/decrypt atempts in this code thats why it looks big,
I can't shrink it unless I remove one of methods-
openssl2 function is using:
aes_init - to init openssl and EVP_BytesToKey to create key from password
aes_encrypt - to encypt
aes_decrypt - to decrypt
openssl2 is initializing aes, performs encrypt and decrypt and prints the result -
openssl function is using:
encrypt - to encrypt
decrypt - to decrypt
handleErrors - doesn't matter
This one is different in terms of key handling, does not derive key from password, key is already provided, taken from openssl command
openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md sha1 -p
- This is just using https://github.com/bricke/Qt-AES
all in single procedure
Best,
Marek -
-
As I said - your code isn't very readable. Please provide one example, no classes, nothing around so we can actually compile it here.
-
As I said - your code isn't very readable. Please provide one example, no classes, nothing around so we can actually compile it here.
@Christian-Ehrlicher ok just a minute
best,
Marek -
in terms of adding '\0'
I think echo command has a switch -n which tells whether to add \n to the end of the string, I tried both optionsAs I understand this should give the same result as openssl command since it is using key taken from openssl command
$ echo "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md sha1 -p key=580D5BAA02014A40B0E30C6E82B60EA5 iZ5IdMK9pkAg0HRF38mHNQ== $ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -pbkdf2 -md sha1 -p key=580D5BAA02014A40B0E30C6E82B60EA5 1mt3AKZ9fpLCgLIlPIOkHA==
void EncryptMgr::opensslShort() { qDebug()<<"BEGIN openssl"; /* A 128 bit key */ unsigned char *key = (unsigned char *)"580D5BAA02014A40B0E30C6E82B60EA5"; /* Message to be encrypted */ unsigned char *plaintext = (unsigned char *)"letmein"; /* Buffer for ciphertext. Ensure the buffer is long enough for the * ciphertext which may be longer than the plaintext, dependant on the * algorithm and mode */ unsigned char ciphertext[128]; int ciphertext_len; int len; int plaintext_len=strlen ((char *)plaintext); EVP_CIPHER_CTX *ctx; /* Initialise the library */ ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); OPENSSL_config(NULL); /* Encrypt the plaintext */ if(!(ctx = EVP_CIPHER_CTX_new())) qDebug()<<"some errors"; /* Initialise the encryption operation. IMPORTANT - ensure you use a key * In this example we are using 128 bit AES (i.e. a 128 bit key). */ if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key,NULL)) qDebug()<<"some errors"; /* Provide the message to be encrypted, and obtain the encrypted output. * EVP_EncryptUpdate can be called multiple times if necessary */ if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) qDebug()<<"some errors"; ciphertext_len = len; /* Finalise the encryption. Further ciphertext bytes may be written at * this stage. */ if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors(); ciphertext_len += len; /* Do something useful with the ciphertext here */ QByteArray arr; for(int i=0;i<ciphertext_len;i++) { arr[i]=ciphertext[i]; } QByteArray str_cipher=QByteArray::fromRawData(reinterpret_cast<char*>(ciphertext), ciphertext_len); qDebug()<<"EncryptMgr::openssl str_cipher:"<<str_cipher.toBase64()<<" second method:"<<arr.toBase64()<<" len:"<<ciphertext_len; EVP_CIPHER_CTX_free(ctx); /* Clean up */ EVP_cleanup(); ERR_free_strings(); }
Best,
Marek -
This is a minimal example which also prints out the same as the command line:
auto ciphertext = reinterpret_cast<const unsigned char*>("letmein"); const int c_len = strlen(reinterpret_cast<const char*>(ciphertext)); int f_len1 = 0; int f_len2 = 0; auto keyIn = reinterpret_cast<const unsigned char*>("myPassword"); int k_len = strlen(reinterpret_cast<const char*>(keyIn)); unsigned char keyOut1[16]; PKCS5_PBKDF2_HMAC_SHA1("myPassword", k_len, nullptr, 0, 5, sizeof(keyOut1), keyOut1); EVP_CIPHER_CTX* e = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(e); EVP_EncryptInit_ex(e, EVP_aes_128_ecb(), nullptr, keyOut1, nullptr); std::vector<unsigned char> dataOut(c_len + EVP_CIPHER_CTX_block_size(e)); EVP_EncryptUpdate(e, dataOut.data(), &f_len1, ciphertext, c_len); EVP_EncryptFinal_ex(e, dataOut.data() + f_len1, &f_len2); EVP_CIPHER_CTX_free(e); qDebug() << QByteArray::fromRawData(reinterpret_cast<char*>(dataOut.data()), f_len1 + f_len2).toBase64();
--> "iwY4XIcGLATKRyyP+n377w=="
enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 -md sha1 iwY4XIcGLATKRyyP+n377w==
-
This is a minimal example which also prints out the same as the command line:
auto ciphertext = reinterpret_cast<const unsigned char*>("letmein"); const int c_len = strlen(reinterpret_cast<const char*>(ciphertext)); int f_len1 = 0; int f_len2 = 0; auto keyIn = reinterpret_cast<const unsigned char*>("myPassword"); int k_len = strlen(reinterpret_cast<const char*>(keyIn)); unsigned char keyOut1[16]; PKCS5_PBKDF2_HMAC_SHA1("myPassword", k_len, nullptr, 0, 5, sizeof(keyOut1), keyOut1); EVP_CIPHER_CTX* e = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(e); EVP_EncryptInit_ex(e, EVP_aes_128_ecb(), nullptr, keyOut1, nullptr); std::vector<unsigned char> dataOut(c_len + EVP_CIPHER_CTX_block_size(e)); EVP_EncryptUpdate(e, dataOut.data(), &f_len1, ciphertext, c_len); EVP_EncryptFinal_ex(e, dataOut.data() + f_len1, &f_len2); EVP_CIPHER_CTX_free(e); qDebug() << QByteArray::fromRawData(reinterpret_cast<char*>(dataOut.data()), f_len1 + f_len2).toBase64();
--> "iwY4XIcGLATKRyyP+n377w=="
enc_test$ echo -en "letmein" |openssl enc -aes-128-ecb -nosalt -k 'myPassword' -a -iter 5 -md sha1 iwY4XIcGLATKRyyP+n377w==
@Christian-Ehrlicher Thanks man, this works for me ;)
When I find some time I try to find bug in my code.Best Regards,
Marek