Decrypt AES with OpenSSL & Qt 5.5.1 Win32 VS2013
-
Thank you!
But no luck, it won't compile. 5 errors.
C2061: syntax error : identifier 'QIODevice' C2065: 'QIODevice' : undeclared identifier C2065: 'file' : undeclared identifier C2448: 'QCA::Hash::update' : function-style initializer appears to be a function definition C2061: syntax error : identifier 'QIODevice'
-
Where did you get QCA from ?
-
@SGaist Thank you for asking. I got it from http://delta.affinix.com/qca/ (qca-2.1.0.tar.gz).
Edit: Did find a newer version @ https://www.freshports.org/devel/qca-qt5/ (qca-2.1.1.tar.xz) and i was able to compile it. At least the debug files did compile. But the big problem is
if(!QCA::isSupported("aes128")) { qDebug() << "No AES 128 supported ..."; } if(!QCA::isSupported("aes128-cbc")) { qDebug() << "No AES 128 CBC supported ..."; } if(!QCA::isSupported("aes128-cbc-pkcs7")) { qDebug() << "No AES 128 CBS pkcs7 supported ..."; }
According to the docs http://delta.affinix.com/docs/qca/ my version does not support AES CBC at all so it is worthless to me atm. Did i something wrong here?
win32: LIBS += -L$$PWD/qca/lib/ -lqca-qt5d INCLUDEPATH += $$PWD/qca/include DEPENDPATH += $$PWD/qca/include
and
#include <QtCrypto/QtCrypto>
Thanks!
-
CBS ? Don't you mean CBC ? If CBC, then yes it does, just take a look at QCA's code.
Before calling these function did you initialize QCA ?
Also, do you have OpenSSL in your PATH environment variable when running the application ?
-
Yes, CBC, sorry.
I did put a QCA::Initializer init; after ui->setupUi(this); And yes, Openssl is in my paths env (C:\OpenSSL-Win32\bin), i can call openssl.exe from command line.
cmake tells me:
qca-botan off qca-cyrus-sasl off qca-gcrypt off qca-gnupg on qca-logger on qca-nss off qca-ossl on qca-pkcs11 off qca-softstore on
Do you know if i need one or more plugins to use AES 128 CBC?
-
I've mastered the installation now. After building it with Qt Creator i went to the build directory and executed a nmake install. After editing the include paths i also had to add CONFIG += crypto in my pro file. So far no more AES128 CBC not supported errors. But still no luck in decrypting my string.
QString ciphertext = "PpUr+LMHvaKmf0q6J7Oyzo4jbFO5kfWyXl0d8nD3hyM="; QString key1 = "098f6bcd4621d373cade4e832627b4f6"; QString iv1 = "507055722b4c4d4876614b6d66307136"; QByteArray key; key = key1.toLatin1(); QByteArray iv; iv = iv1.toLatin1(); QCA::SecureArray arg = ciphertext.toLatin1(); QCA::Cipher cipher(QString("aes128"),QCA::Cipher::CBC, QCA::Cipher::NoPadding, QCA::Decode, key, iv); QCA::SecureArray plainText = cipher.update(arg); if(!cipher.ok()) { qDebug() << "update fail"; } plainText = cipher.final(); if(!cipher.ok()) { qDebug() << "final fail"; } qDebug() << "plainText.data(): " << plainText.data();
The decrypted text should be Dr. Test and password is test. The iv are the fist 16 bytes from the ciphertext and the password is a md5 hash from test. Works in openssl command line. I get a qDebug final fail result.
Any ideas about that?
Thanks!
-
I'm doing something wrong and i can't figure out what. Changed to utf8, plain key and iv, vise versa, but somehow i won't get this example decrypted. It does work this way in the openssl command line tool.
So far i did not find any example code that used a custom key and iv, only random generated ones. Also gave QCA::SymmetricKey::SymmetricKey(key) and QCA::InitializationVector::InitializationVector(iv) a chance, did not really help.
Any ideas?
-
Your code doesn't match all the openssl line options.
-a -A
means that you must first decode your Base64 encoded string. -
@SGaist Thanks! I don't know why but i did forget about the base64 decode. After changing from toLatin1 to toUtf8 and decode the base64 string i don't get the final error anymore. But i won't get the expected plain text only
o????:??????a?s?]??Iy?[W6???l??(f?$?I{??^ ????Cï5?
same result if i use
qDebug() << "process: " << QCA::SecureArray(cipher.process(decodedBase64.toUtf8())).data();
Maybe the utf8 conversion is the problem but it won't take a QString. I get the same result if i append the string to a QByteArray. Btw. noting changes if i use QByteArray to decode base64 or QCA::Base64 decoder(QCA::Decode);
At least the final error is gone, that's some progress! ;)
Edit: And i added "md5" as crypto service provider because it was encoded this way. md5 is in the list of providers, so i hope i implemented this correctly.
QCA::Cipher cipher(QString("aes128"), QCA::Cipher::CBC, QCA::Cipher::NoPadding, QCA::Decode, key, iv, "md5");
But cipher.provider()->name(); returns "qca-ossl".
-
Do you mean that you passed your original string through md5 before encrypting it ?
-
Can you show the complete procedure ?
-
Thanks for asking. This is the VB code to encrypt the string:
Dim AES As New RijndaelManaged Dim md5 As New MD5CryptoServiceProvider Dim key() As Byte = md5.ComputeHash(Encoding.UTF8.GetBytes(password)) md5.Clear() AES.Key = key AES.GenerateIV() Dim iv() As Byte = AES.IV Dim ms As New MemoryStream ms.Write(iv, 0, iv.Length) Dim cs As New CryptoStream(ms, AES.CreateEncryptor, CryptoStreamMode.Write) Dim data() As Byte = System.Text.Encoding.UTF8.GetBytes(string) cs.Write(data, 0, data.Length) cs.FlushFinalBlock() Dim encoded() As Byte = ms.ToArray() Return (Convert.ToBase64String(encoded)) cs.Close() AES.Clear()
As far as i can tell is the password and the string are utf8 bytes and the password is the md5 hash of it. I did try to pass it through
QCA::SecureArray key = QCA::SecureArray::SecureArray(password);
before and after utf8 and md5. So far no luck.
Thank you!
-
And this is my attempt:
QString MainWindow::decryptString(QString password, QString encodedString) { // final decodec string QString decodedString; // get the iv QByteArray array(encodedString.left(16).toStdString().c_str(), encodedString.left(16).size()); QCA::SecureArray iv = array.toHex(); // decode base64 QCA::Base64 decoder(QCA::Decode); const char* decoded = decoder.decodeString(encodedString).toStdString().c_str(); QCA::SecureArray key = QByteArray(QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex()); QCA::SecureArray arg = decoded; QCA::Cipher cipher(QString("aes128"), QCA::Cipher::CBC, QCA::Cipher::NoPadding, QCA::Decode, key, iv); QCA::SecureArray plainText = cipher.update(arg); if(!cipher.ok()) { qDebug() << "update Fail"; } cipher.final(); if(!cipher.ok()) { qDebug() << "final fail"; } qDebug() << "process: " << QCA::SecureArray(cipher.process(decoded)).data(); decodedString = plainText.data(); qDebug() << "Decoded: " << decodedString; return decodedString; }
I call it like:
qDebug() << "decoded: " << decryptString("test", "PpUr+LMHvaKmf0q6J7Oyzo4jbFO5kfWyXl0d8nD3hyM=");
The only step i masted was getting rid of the final fail, but i don't know if that was really the case. Not sure how, i changed this so often, i don't even know how much time i spend on this. I didn't think it can be that difficult to use it.
So far i still did not fine one single example code using qca with aes128cbc and custom iv and key. Very, very strange.
Any ideas?
Thanks!
-
Do you mean this example ?
-
Just replace the random key and iv by yours.
-
I did. That was my first idea, did not work. Id did check the key and iv output, same as i use with openssl, does work in openssl, does not work in Qt / QCA - at least not the way i do it. I don't know, maybe i miss something in general or just just a tiny mistake, but after days and hours, i can confirm, it won't work for me.
-
I took the example as is, replaced key and iv by
QByteArray key("098f6bcd4621d373cade4e832627b4f6"); QByteArray iv("d8e8fca2dc0f896fd7cb4cb0031ba249");
and it's working fine.
-
If you can tell me why this code
QString decodedString; QCA::Initializer init; QByteArray array(encodedString.left(16).toStdString().c_str(), encodedString.left(16).size()); QCA::SecureArray iv = array.toHex(); QCA::Base64 decoder(QCA::Decode); QCA::SecureArray decoded = decoder.decodeString(encodedString).toStdString().c_str(); QCA::SecureArray key = QByteArray(QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex()); QCA::Cipher cipher(QString("aes128"), QCA::Cipher::CBC, QCA::Cipher::NoPadding, QCA::Decode, key, iv); QCA::SecureArray plainText = cipher.update(decoded); if(!cipher.ok()) { qDebug() << "update Fail"; } plainText = cipher.final(); if(!cipher.ok()) { qDebug() << "final fail"; } qDebug() << "process: " << QCA::SecureArray(cipher.process(decoded)).data(); QString decodedString = plainText.data(); qDebug() << "Decoded: " << decodedString;
is not working, it may help me. If you tell me some code is working for you, it does not. This is btw. taken from the example, i did not change anything beside adding key and iv.