Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Solved Decrypt AES with OpenSSL & Qt 5.5.1 Win32 VS2013

    General and Desktop
    openssl qt 5.5.1 windows vs 2013 decrypt
    3
    42
    16678
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Q
      qDebug last edited by qDebug

      Hello!

      Did hit a dead end trying to decode a AES encoded string using Openssl 1.0.1s and Qt 5.5.1 Win32 Visual Studio 2013. Since it works on the commandline with openssl.exe it has to be my code or implementation. I'm using Qt Creator 3.5.1.

      After compiling Openssl (shared libs + debug) i just added

      win32: LIBS += -L$$PWD/openssl/lib/ -llibeay32
      INCLUDEPATH += $$PWD/openssl/include
      DEPENDPATH += $$PWD/openssl/include
      

      to my .pro file, run qmake and did build all and run the app. But so far only crashes without any error.

      Here is my code:

      #include <openssl/conf.h>
      #include <openssl/evp.h>
      #include <openssl/err.h>
      
      // password: test
      // cypertext: Dr. Test
      // works: PpUr+LMHvaKmf0q6J7Oyzo4jbFO5kfWyXl0d8nD3hyM= | openssl enc -d -a -A -aes-128-cbc -iv 507055722b4c4d4876614b6d66307136-K 098f6bcd4621d373cade4e832627b4f6
      
      QString cypher = "PpUr+LMHvaKmf0q6J7Oyzo4jbFO5kfWyXl0d8nD3hyM=";
      QString pw_md5 = "098f6bcd4621d373cade4e832627b4f6";
      QString iv16 = "507055722b4c4d4876614b6d66307136";
      
      ERR_load_crypto_strings();
      OpenSSL_add_all_algorithms();
      OPENSSL_config(NULL);
      
      unsigned char *ciphertext = (unsigned char*) cypher.data();
      int ciphertext_len = static_cast< int >(cypher.size());
      unsigned char *key = (unsigned char*) pw_md5.data();
      unsigned char *iv = (unsigned char*) iv16.data();
      unsigned char *plaintext = (unsigned char*) "";
      
      qDebug() << "ciphertext: " << ciphertext;
      qDebug() << "ciphertext_len: " << ciphertext_len;
      
      EVP_CIPHER_CTX *ctx;
      
      int len;
      int plaintext_len;
      
      if(!(ctx = EVP_CIPHER_CTX_new()))
      {
      	ERR_print_errors_fp(stderr);
      }
      
      if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
      {
      	ERR_print_errors_fp(stderr);
      }
      
      if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
      {
      	ERR_print_errors_fp(stderr);
      }
      plaintext_len = len;
      
      if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len))
      {
      	ERR_print_errors_fp(stderr);
      }
      plaintext_len += len;
      
      EVP_CIPHER_CTX_free(ctx);
      EVP_cleanup();
      ERR_free_strings();
      
      qDebug() << "plaintext_len: " << plaintext_len;
      qDebug() << "plaintext: " << plaintext;
      

      if i set

      int ciphertext_len = 0;
      

      i get at least a final block length error (after i quit the app) and the app won't crash. If i set it to 44 manually, the app still crashes.

      Any ideas?

      Thanks!

      1 Reply Last reply Reply Quote 0
      • hskoglund
        hskoglund last edited by

        Hi, don't know about the OpenSSL block lengths problem, but the reason you're crashing I think is because you're allocating memory badly, for example
        unsigned char *plaintext = (unsigned char*) ""; is almost always guaranteed to crash.
        Why not skip the QStrings, do something simpler like this:

        ...
        unsigned char cypher[] = "PpUr+LMHvaKmf0q6J7Oyzo4jbFO5kfWyXl0d8nD3hyM=";
        unsigned char pw_md5[] = "098f6bcd4621d373cade4e832627b4f6";
        unsigned char iv16[] = "d8e8fca2dc0f896fd7cb4cb0031ba249";
        
        ERR_load_crypto_strings();
        OpenSSL_add_all_algorithms();
        OPENSSL_config(NULL);
        
        unsigned char *ciphertext = cypher;
        int ciphertext_len = sizeof(cypher) - 1;
        unsigned char *key = pw_md5;
        unsigned char *iv = iv16;
        unsigned char plaintext[1024];
        ...
        

        Now the app shouldn't crash, so you can try debugging the OpenSSL decrypting stuff...

        1 Reply Last reply Reply Quote 1
        • Q
          qDebug last edited by

          Thanks to you, no more crashing. :D

          Tank you!

          Still getting wrong last black error. But at least i can try to fix that somehow. I was guessing some Qt users may use Openssl and got experience using it with Qt.

          1 Reply Last reply Reply Quote 0
          • SGaist
            SGaist Lifetime Qt Champion last edited by

            Hi,

            Depending on your needs the QCA module might be something to look into.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            Q 1 Reply Last reply Reply Quote 0
            • Q
              qDebug @SGaist last edited by qDebug

              @SGaist Thanks, but it is no option for me. Did load qca-2.1.0 and also did try to compile it on Windows VS2013 and cmake. No chance i will get this running without a step my step tutorial for Win. I did try to compile it on Ubuntu, no problem, works instantly, Windows, nah. I will look into this module again if i ever reach a level called ultra skilled hacker.

              Also tryed Crypto++ and was able to get some code running, but the sample codes do not work for me and the docs are not really helpful.

              1 Reply Last reply Reply Quote 0
              • SGaist
                SGaist Lifetime Qt Champion last edited by SGaist

                To avoid the need to level-up that high: open the QCA project in Qt Creator and build it with the Kit you are using for your project, then install it and you should be done. IIRC, you can even choose the install target from the list in the Project panel.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply Reply Quote 1
                • Q
                  qDebug last edited by

                  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'
                  
                  1 Reply Last reply Reply Quote 0
                  • SGaist
                    SGaist Lifetime Qt Champion last edited by

                    Where did you get QCA from ?

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    Q 1 Reply Last reply Reply Quote 0
                    • Q
                      qDebug @SGaist last edited by qDebug

                      @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!

                      1 Reply Last reply Reply Quote 0
                      • SGaist
                        SGaist Lifetime Qt Champion last edited by

                        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 ?

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply Reply Quote 0
                        • Q
                          qDebug last edited by qDebug

                          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?

                          1 Reply Last reply Reply Quote 0
                          • Q
                            qDebug last edited by

                            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!

                            1 Reply Last reply Reply Quote 0
                            • Q
                              qDebug last edited by

                              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?

                              1 Reply Last reply Reply Quote 0
                              • SGaist
                                SGaist Lifetime Qt Champion last edited by

                                Your code doesn't match all the openssl line options. -a -A means that you must first decode your Base64 encoded string.

                                Interested in AI ? www.idiap.ch
                                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                Q 1 Reply Last reply Reply Quote 1
                                • Q
                                  qDebug @SGaist last edited by qDebug

                                  @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".

                                  1 Reply Last reply Reply Quote 0
                                  • SGaist
                                    SGaist Lifetime Qt Champion last edited by

                                    Do you mean that you passed your original string through md5 before encrypting it ?

                                    Interested in AI ? www.idiap.ch
                                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                    1 Reply Last reply Reply Quote 0
                                    • Q
                                      qDebug last edited by qDebug

                                      The password / key was md5 hashed.

                                      key = md5(utf8(password));
                                      

                                      and the iv are the first 16 bytes from the base64 string.

                                      Edit: Not the key of course, the iv are the first 16 bytes from the base64 string.

                                      1 Reply Last reply Reply Quote 0
                                      • SGaist
                                        SGaist Lifetime Qt Champion last edited by

                                        Can you show the complete procedure ?

                                        Interested in AI ? www.idiap.ch
                                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                        1 Reply Last reply Reply Quote 0
                                        • Q
                                          qDebug last edited by

                                          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!

                                          1 Reply Last reply Reply Quote 0
                                          • Q
                                            qDebug last edited by

                                            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!

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post