Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Is there a way to make output from QCryptographicHash readable QByteArray?



  • Good afternoon.
    I spent half of the afternoon trying to find a solution and I must be dumb or not know something.

    The task:
    internally I use this one-liner to create hashed passwords:

    python -c "from passlib.hash import sha512_crypt; import getpass,string,random; print(sha512_crypt.using(salt=''.join([random.choice(string.ascii_letters + string.digits) for _ in range(16)]),rounds=5000).hash(getpass.getpass()))"
    

    but recently I had a need to ask non-technical people to do the same, so I can deal only with hashes and not their passwords. Since it is not urgent I decided to play a bit and came out with this code (compilable excerpts).
    Method generateRndStr() returns QString and does generate random string from the pool of allowed characters and desired length passed as a parameter.
    Method crypt is from unistd.h

    QByteArray CryptoClass::getHash(const QByteArray &data) const {
        QCryptographicHash *hash = new QCryptograhicHash(QCryptographicHash::Sha512);
        hash->addData(crypt(data.constData(),generateRndStr(16).toUtf8().constData()));
    return hash->result();
    

    crypt() expects const char * as parameters so QByteArray::constData() seems to be ok? It returns char * so I assume it is compatible with QByteArray (I also checked printing raw values to stdout: salt, password and result of crypt() are as to be expected, all printable chars.

    At any rate, when I wanted to compare the output from the python one-liner and my routine I run into trouble - how the hell do I convert this to text? I tried QString but that got me only running in circles and garbage on the screen. Same with printf to the stdout.
    What do I miss here? Or is my approach somehow wrong?

    EDIT: example output from the python one-liner and where do I want to get to:
    $6$Lt5bExFakB7nrZEN$3KHS5HLNe8UwSxGQY6foF3vJiv/VxiGi2WWvz04c4OpoXgIB37GeaF6ILFtGhHZSMA7hL/6nGmEHeRRADXXWQ1


  • Lifetime Qt Champion

    @artwaw said in Is there a way to make output from QCryptographicHash readable QByteArray?:

    And it is on the heap since I don't know how to initialise it otherwise (method selection).

    I don't understand this? Why does

    QCryptographicHash hash(QCryptographicHash::Sha512);

    not work?

    So you say QByteArray::toBase64 should suffice?

    Yes


  • Lifetime Qt Champion

    Hashes are normally printed as base64 and so it's $6$Lt5bExFakB7nrZEN$3KHS5HLNe8UwSxGQY6foF3vJiv/VxiGi2WWvz04c4OpoXgIB37GeaF6ILFtGhHZSMA7hL/6nGmEHeRRADXXWQ1

    QCryptographicHash *hash

    You leak this instance, why do you create it on the heap at all?


  • Lifetime Qt Champion

    Hi

    • I must be dumb or not know something.
      We all know here you are not dumb and there is a vaste universe of stuff we dont know but

    QByteArray::constData() should be perfectly fine
    but make sure the bytearray lives long enough for for crypt() to use it while still in scope.



  • @Christian-Ehrlicher my bad but this is inly excerpt. In the program it is a member and is deleted in the destructor.
    And it is on the heap since I don't know how to initialise it otherwise (method selection). One of the constrains I face is that it has to be SHA-512 and only that.

    So you say QByteArray::toBase64 should suffice?

    @mrjj I examined and tested the code from which excerpts are here, worked over 100 times both in loop with no wait and waiting for user input.


  • Lifetime Qt Champion

    @artwaw said in Is there a way to make output from QCryptographicHash readable QByteArray?:

    And it is on the heap since I don't know how to initialise it otherwise (method selection).

    I don't understand this? Why does

    QCryptographicHash hash(QCryptographicHash::Sha512);

    not work?

    So you say QByteArray::toBase64 should suffice?

    Yes



  • This post is deleted!


  • IT WORKS!
    Thank you!

    @Christian-Ehrlicher That works, of course. But outside of the example it looks like this:
    I wrapped all those hash-generating bits into a small class. For convenience, I have there:

    private:
        QRandomGenerator generator;
        QCryptographicHash *hash;
    

    In the constructor I init the generator and the hash. So I have hash = new QCryptographicHash(QCryptographicHash::Sha512); that is later deleted in the destructor. It apparently is a weak day for me but I failed to find a way of this private member NOT to be on the heap.

    EDIT:
    @JonB I saw your comment :)
    I understood, just at this hour I am not entirely online, just from time to time :)



  • @artwaw
    Personally I don't worry about heap vs stack as some others do, when I did Python it's all heap anyway. And sometimes I heap to avoid include dependencies in header files.

    But why can't you have QCryptographicHash hash(QCryptographicHash::Sha512); as the member variable instead of pointer?



  • @JonB When I do:

    private:
        QCryptographicHash hash(QCryptographicHash::Sha512);
    

    I get instant /Users/(username)/cpp/512hash/cryptoclass/cryptoclass.h:24: error: no type named 'Sha512' in 'QCryptographicHash'



  • @artwaw
    Ah! That will be because you are in the "sometimes I heap to avoid include dependencies in header files" I mentioned :)

    Intentionally or not, in your .h file you have preceded this line with

    class QCryptographicHash;
    

    That allows QCryptographicHash * declarations to the incomplete type.

    You will need

    #include <QCryptographicHash>
    

    to make the declaration acceptable. If that is what you wish to do.

    I see for example you alreday have

    QRandomGenerator generator;
    

    so you have chosen to do that one with include.



  • @JonB Believe me or not but I do have it.
    0d4539e8-71d3-4683-8004-459706d7945c-image.png



  • @artwaw
    And that's in the .h file, not just in the .cpp?



  • @JonB Yes. I tend to do all includes in the header.



  • @artwaw said in Is there a way to make output from QCryptographicHash readable QByteArray?:

    I get instant /Users/(username)/cpp/512hash/cryptoclass/cryptoclass.h:24: error: no type named 'Sha512' in 'QCryptographicHash'

    Then I have no idea why you get a "no type" error for

    QCryptographicHash hash(QCryptographicHash::Sha512);
    

    in a .h but not in a .cpp or why

    hash = new QCryptographicHash(QCryptographicHash::Sha512);
    

    is acceptable.



  • @JonB I can live with one pair of new/delete :)

    Thank you all who contributed and especially to @Christian-Ehrlicher for pointing me out the obvious.


Log in to reply