New SimpleCrypt page



  • I have just added a "page":http://developer.qt.nokia.com/wiki/Simple_encryption in the Snippets category that details a class to deal with some simple encryption and decryption. I would really welcome any comments you may have, on the text of the Wiki page, the API of the class, or the strength of the encryption algorithm used. Note that I am not an expert in cryptography :-)

    Would it be useful to add a section discussing the actual algorithm used in the class?



  • Hi Andre,

    nice entry. Thanks for sharing the code.



  • Andre, I think it's useful.

    This kind of cipher as you explain seems simple and efficient, just what a lot of mobile developers needs to give to their applications the option for data to be "unreadable by others".

    I am thinking to those that I am developing: "naijanimi":projects.forum.nokia.com/naijanimi (at projects.forum.nokia.com/naijanimi; restricted access) It is at an early stage but I should (to be clear: I SHOULD ;) ) go ahead very fast this next w.e. The encryption capability, not really required by the customer, is missing but needed: it is an application to send free SMS and some data (just user and login, phone number etc) are saved on the phone and if they are encrypted it is best.

    Edit: make link into real link, and added note on restricted access to page; Andre



  • I am glad people seem to appreciate the snippets I have posted so far.

    [quote author="Andre" date="1300457411"]Would it be useful to add a section discussing the actual algorithm used in the class?[/quote]

    Does anyone think it is -possible- nessecairy to document this in more detail in the article?



  • Hi Andre, I can if you explain to me a bit more what do yo have in mind. What I am thinking is to use this class in an application that I am building in these days, so the reference code can became a set of snippets for users that want to use, while the application itself can be a usage sample (it is shared on projects.forum.nokia.com/najianimi). The informations can be collected in the wiki integrating the page you have already wrote.



  • I'm not sure the page needs a lot of snippets illustrating the use. It seems quite clear to me. Or do you think it needs more examples?



  • Andre, I was no clear in my thought. The page is clear, as is, with the snippet. I agree that a wiki page with too much code became confusing. What I mean is that integrating your page, with a little more documentation about encryption and a project that can be an example (that use in a precise vode source your class) can be useful.

    Usually what I find in documentation on the net regarding encryption or similar, is too much code or too much teory.



  • thank you Andre , a very good work



  • Sure ! :) It's a great starting point.



  • Nice entry Andre.



  • I am currently working on a version 2, with these added features:

    • optional integrity checks using a checksum or a cryptographic hash
    • error reporting
    • slightly higher security due to added random character. That should make it harder to guess the first byte of the key based on the fact that there are only a limited number of characters used normally. Should increase effective key length by an guestimated 3 bits.


  • I have just uploaded a modified version that implements the above features.



  • I am waiting in the shade... When I start (hope tomorrow) I can get the last version :)



  • If you miss the documentation tools discussion: I've split it out to a "new thread":http://developer.qt.nokia.com/forums/viewthread/4619/



  • I have added a "separate page":http://developer.qt.nokia.com/wiki/SimpleCrypt_algorithm_details that details the algorithm and the layout of the cypher text. Of course, I also added a link from the main page.



  • Hi Andre,
    First: Thanks for sharing the code.

    Second: You've got some typos in the Example usage code.

    • Name of the Class: SimpleCypt --> SimpleCrypt
    • crypto.setCompression(SimpleCrypto::CompressionAlways)
      ** crypto.setCompressionMode(SimpleCrypt::CompressionAlways);
    • crypto.setIntegrityProtection(SimpleCrypto::ProtectHash);
      ** crypto.setIntegrityProtectionMode(SimpleCrypt::ProtectionHash);
    • SimpleCrypt.ErrorNoError --> SimpleCrypt::ErrorNoError

    Third:
    The String Encryption and Decryption works fine, but for the binary version I seem to be having some difficulties.

    my main.cpp
    @
    #include "simplecrypt.h"

    #include <QString>
    #include <QDebug>
    #include <QBuffer>
    #include <QDataStream>

    int main(){
    QString txStr = "Hello world!";

    SimpleCrypt crypto(Q_UINT64_C(0x7F29B208)); //some random number
    // crypto.setCompressionMode(SimpleCrypt::CompressionAlways);
    // crypto.setIntegrityProtectionMode(SimpleCrypt::ProtectionHash);
    QBuffer txB;
    QDataStream s(&txB);
    s << txStr;

    QByteArray cypherBytes = crypto.encryptToByteArray(txB.data());
    if (crypto.lastError() == SimpleCrypt::ErrorNoError) {
    qDebug() << cypherBytes;
    }

    SimpleCrypt cryptu(Q_UINT64_C(0x7F29B208)); //some random number
    QByteArray plainBytes = cryptu.decryptToByteArray(cypherBytes);
    if (!cryptu.lastError() == SimpleCrypt::ErrorNoError) {
    qDebug() << "decrypt error";
    return 0;
    }
    qDebug() << plainBytes;

    QString rxStr;
    QBuffer rxB(&plainBytes);
    QDataStream rs(&rxB);
    rs >> rxStr;
    qDebug() << rxStr;
    return 0;
    }
    @

    My Output (console):

    "??Sß+"
    ""
    ""

    What have I missed or using incorrectly?

    Thanks again for the contribution.



  • So I've played a bit around I've come to the conclusion that I'm using QDataStream incorrectly.

    My Test Code: main.cpp
    @
    #include <QString>
    #include <QDebug>
    #include <QBuffer>
    #include <QDataStream>
    int main(){
    QString txStr = "Hello world!";
    QString rxStr;

    QBuffer txB;
    txB.open(QIODevice::ReadWrite);
    QDataStream s(&txB);
    qDebug() << txB.size();
    s << txStr;
    qDebug() << txB.size();
    s >> rxStr;
    qDebug() << rxStr;
    return 0;
    }
    @

    My Output:
    0
    28
    ""

    So the buffer is being filled but not correctly being read out.. why not?



  • That's an easy question. Your problem is the stream position:

    you write to the stream, then start reading after the written bytes :-)

    try out the following:

    @
    #include <QString>
    #include <QDebug>
    #include <QBuffer>
    #include <QDataStream>
    int main()
    {
    QString txStr = "Hello world!";
    QString rxStr;

    QBuffer txB;
    txB.open(QIODevice::WriteOnly);
    QDataStream s(&txB);
    qDebug() << txB.size();
    s << txStr;
    qDebug() << txB.size();
    txB.close(); // sets stream position to 0 !!!
    
    txB.open(QIODevice::ReadOnly);
    QDataStream s2(&txB);
    s2 >> rxStr;
    qDebug() << rxStr;
    return 0;
    

    }
    @

    or use a seek in between

    @
    #include <QString>
    #include <QDebug>
    #include <QBuffer>
    #include <QDataStream>
    int main()
    {
    QString txStr = "Hello world!";
    QString rxStr;

    QBuffer txB;
    txB.open(QIODevice::WriteOnly);
    QDataStream s(&txB);
    qDebug() << txB.size();
    s << txStr;
    qDebug() << txB.size();
    txB.seek(0); // sets stream position to 0 !!!
    s >> rxStr;
    qDebug() << rxStr;
    return 0;
    

    }
    @

    I did not compile the code, so it might contain typos



  • Aha, got it all sorted out, thanks

    I had my suspicions on that, but thought that the "<<" and ">>" operators may use seperate index variables.

    Andre: it would be great if you could incorporate in the Example usage code the following so it works out of the box.

    @
    buffer.open(QIODevice::WriteOnly);
    buffer.close();
    buffer.open(QIODevice::ReadOnly);
    @

    Because newbies like myself:

    • copy + paste + compile
      ** if it works -> adapt to needs
      ** if it doesn't -> get lost in the simplest things

    Although I must admit that I am learning loads of things through all these problems I get myself into.

    Gerolf: Once again thanks for your quick and effective response.



  • paucoma, thank you for your comments and suggestions. I have changed the wiki page accordingly. I am glad you solved the problem, and that it turned out the class itself was not at fault ;-)

    I must admit that I wrote the examples directly in the wiki page, and thats when errors like these happen. Sorry about that! I hope the current version is more managable? Note that I was talking about "at the other end", implying that the decryption code was not meant to be used in the same function (and thus, implicitly, with the same buffer).



  • Thanks Andre for making the modifications.

    I have corrected myself a few other details I found.

    P.S. I didn't know that I had such a priviledge.



  • Thanks for your effort, I really appreciate it. If you want, you're welcome to update it yourself in the wiki article :-)



  • Hi Andre,

    one suggestion to the wiki page:
    In the section SimpleCrypt in use it would be nice to have a list of the encryp/decrypt functions. You state thete are two times 4, but not the names :-)
    this means searching inside the code :-)

    The rest sound really god. Thanks for the article.



  • [quote author="Gerolf" date="1300958192"]Hi Andre,

    one suggestion to the wiki page:
    In the section SimpleCrypt in use it would be nice to have a list of the encryp/decrypt functions. You state thete are two times 4, but not the names :-)
    this means searching inside the code :-)

    The rest sound really god. Thanks for the article.[/quote]

    Fair enough, done. :-)

    Thanks for the praise.



  • Hi Andre,

    I'm currently reading your second article, and found the following "here":http://developer.qt.nokia.com/wiki/SimpleCrypt_algorithm_details#00f4e5788aab6d3546bb433842dbbefc :

    bq. The payload data block’s contents are encrypted with a four byte (quint64) key.

    quint64 is a 64 bit integer, which means 8 byte.

    so also in the snipet page, you say:

    @
    SimpleCrypt crypto(Q_UINT64_C(0x7F29B208)); //some random number
    @

    this is just a 32 bit number, not 64 bit.

    @
    void SimpleCrypt::splitKey()
    {
    m_keyParts.clear();
    m_keyParts.resize(4);
    for (int i=0;i<4;i++) {
    quint64 part = m_key;
    for (int j=i; j>0; j--)
    part = part >> 8;
    part = part & 0xff;
    m_keyParts[i] = static_cast<char>(part);
    }
    }
    @

    this also only uses 4 bytes, not 8.



  • some additional topics:

    in "Decrypted payload":http://developer.qt.nokia.com/wiki/SimpleCrypt_algorithm_details#2d478ba9ee3cf03e338b506b1a0292dc

    SH1 and CRC have the same description:

    bq. In case the Protection Checksum flag has been set, the layout of the decrypted payload looks like this:

    I think this is just a copy paste error.

    As I'm through now, no more things :-)
    Very good article, interesting to read. Thanks.



  • Thank you very much for this catch, Gerolf! You are absolutely right, and this is a big mistake in the algorithm as well. I will take care of fixing this ASAP.



  • OK, fixed on both pages. Very embarrassing, I must say. :(



  • Now it looks good, thanks :-)



  • I tried today SimpleCrypt class and it was very useful.

    Thanks!



  • Glad you like it!



  • Hi Andre.
    First of all, thanks for sharing your code. :-)

    I was playing with this algorithm, but I noticed a strange situation: sometimes these work well, sometimes not.

    This is the string which I have tested :
    10197016915918185882701231384169178913312058269-10750535699546572956586080750006397
    The key is: 13775729

    I tested both with string and binary data (there are several integer values).

    So if I encrypt this string, and then decrypt it, sometimes original string is equal with decrypted string, sometimes differ.



  • You'll have to provide a small testprogram that shows the problem, otherwise I can not help you debug the issue.



  • A small test is something like :

    @
    QString cryptSerialNumber;

    void testCrypt()
    {
    SimpleCrypt processSimpleCrypt(13775729);
    QString uniqueString("10197016915918185882701231384169178913312058269-10750535699546572956586080750006397");
    cryptSerialNumber = processSimpleCrypt.encryptToString(uniqueString);
    }

    void testDecrypt()
    {
    SimpleCrypt processSimpleCrypt(13775729);
    QString uniqueString = processSimpleCrypt.decryptToString(cryptSerialNumber);
    }
    @

    Sometimes decrypted "uniqueString" is the same as the original, but sometimes is :
    1019701691591818588270123138416917891691033658269-10750535699546572956586080750006397, almost the same with original, but not the same :-)



  • Strange. Very, very strange. In such cases, are the cryptSerialNumber the same, or do they differ as well?



  • After encrypt step, I write "cryptSerialNumber" into file.
    In decrypt step, I read it from file.

    I assume it is the same, the file remain unchanged. I'll do more debug to tell you if "cryptSerialNumber" is the same ...



  • Yes, the “cryptSerialNumber” is the same:
    AwNgsVZWVlYFfdbw6is6+srGtTZtFxBm1rc5z8/z1lQNfU74jOk+0bsNs2vMFNlbB5RqAZI/dgJEH79ElSotizgvmf0/xg==

    Yes, is very strange ...



  • Well, at least, that narrows down the issue to the decrypting routine... Issue is: there is nothing in there that I can think of might be influenced by something else than the input string itself. I will have to investigate, but I can not do that right now. I'll need a few days before I get around to doing that. Sorry. I would like to encourage you to try to debug it on your own as well. At the very least, insert some debug statements at strategic places in the code to see what goes on.

    Hmmmm... now that I think about it: it is actually very strange that your encrypted string stays the same. It should be different each time you do the encryption, even on the same input string. That is because a random byte is inserted at the front of the byte array to encrypt (line 115 and 116 from simplecrypt.cpp).



  • [quote author="Andre" date="1315913144"]Hmmmm... now that I think about it: it is actually very strange that your encrypted string stays the same. It should be different each time you do the encryption, even on the same input string.[/quote]

    You are right. But I do the encryption only once. This encryption string I'll write into file only once.
    Then I try to decrypt it several times. And ... sometimes decrypt string = original string, sometimes is very little different.

    [quote author="Andre" date="1315913144"]I will have to investigate, but I can not do that right now. I'll need a few days before I get around to doing that. Sorry.[/quote]
    Thanks for your time, it is not rush. Now I'm very busy with another project, but if I have more time, I'll debug longer ...



  • Hi

    I have tried to reproduce the problem using this code:
    @

    #include <QtCore/QCoreApplication>
    #include "simplecrypt.h"
    #include <QtDebug>

    bool testDecrypt()
    {
    const QString cryptString("AwNgsVZWVlYFfdbw6is6+srGtTZtFxBm1rc5z8/z1lQNfU74jOk+0bsNs2vMFNlbB5RqAZI/dgJEH79ElSotizgvmf0/xg==");
    const QString expectedResult("10197016915918185882701231384169178913312058269-10750535699546572956586080750006397");

    SimpleCrypt crypt(13775729);
    QString result = crypt.decryptToString(cryptString);
    if (result == expectedResult)
        return true;
    
    qDebug() << "Fail: " << result;
    return false;
    

    }

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    int pass(0), fail(0);
    for (int i(0); i<1000000; ++i) {
        if (testDecrypt()) {
            ++pass;
        } else {
            ++fail;
        }
    }
    qDebug() << "Decryption passed" << pass << "times and failed" << fail << "times.";
    
    return 0;
    //return a.exec&#40;&#41;;
    

    }
    @

    My output was:
    @
    Decryption passed 1000000 times and failed 0 times.
    @

    That is: I am not able to see any instability in the algorithm, at least not via this test. That makes it hard for me to figure out why you might be seeing a problem.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.