# New SimpleCrypt page

• Well, the qHash function comes to mind, or perhaps you could use [[doc:QCryptographicHash]]. You add a bit a salt to your pass string, generate a hash, and combine the bits in the resulting hash to create a 64 bit value. If you use MD5, you get a 128bits hash. You could do something like this:

@
QByteArray hash;
QCryptographicHash hasher(Md5);
hasher.addData(salt); //salt is a QByteArray with some random data
hash = hasher.result();

//we now have a QByteArray that is too long with a hash of the password.

//get the contents of the byte array into two quint64's. There are other ways...
quint64 part1, part2;
QBuffer buffer(hash);
QDataStream stream(&buffer);
stream >> part1 >> part2;
key = part1 ^ part2; //combine the two parts

return key;
}
@

Note: brain to editor, not tested.

Edit:
Note that qHash returns a 32 bits result, so you will have to combine two of these to get a 64 bits version. Perhaps using part of the password for hash1, and the other part for hash2, and then combining the result to get a 64 bits key.

I'm not at ease with with hashing and combining stuff :/
How can you do that?
How do you combine 2 unsigned int?

• In the same way I do in the snippet I posted, for instance. I use bitshifting, but that is the same as multiplication by 2-to-the-power-of-n. Basically, what you do is:

# add the two numbers by either:

## using a binary OR operation like I did in my sample.

• Just a note that this appears to be a Vigenere cipher scheme (see http://en.wikipedia.org/wiki/VigenĂ¨re_cipher for details) if you simply want basic scrambling of data to prevent trivial access to the plain text then this could well be sufficient, but it's not very strong. Particularly be careful of using this for long texts.

• Thanks for the note. If I understand the page you link, I'm not sure that the class implements what qualifies as a Vigenere cipher, but I will agree that it does not provide strong cryptography.

The small additional trick is that the code uses the value of the previous code block as part of the key for the next block. That will hinder the kinds of analysis described in the article, if I understand it correctly. The key length is known in this case: 8 bytes, but because the key is mixed with the previously generated cypher text, it does not work to just decrypt the text as eight different cesar cyphers.

• Yes, this is the auto-key variant of vigenere cipher, and is a lot stronger than the basic one.

• Interesting stuff. Perhaps I should try to make a new version (still: keeping it simple!) that is a bit stronger.

• If you do, I'd be tempted to use something like RC4 which while not perfect, is very simple to implement.

• Andre I think you did a great job, at documenting not only usage but also the algorithm. I wish all of Qt's examples were so well thought out ;)

• Great job, easy to use. One question, I tested my app on Debian and Mint and no problem, but on Fedora 17 and Arch
I get "Invalid version or not a cyphertext."

@ QByteArray ba = cypher;

``````char version = ba.at(0);
if (version !=3) {  //we only work with version 3
m_lastError = ErrorUnknownVersion;
qWarning() << "Invalid version or not a cyphertext.";
return QByteArray();
}@``````

• Sorry, no idea. I did not test on these sytems, but I have no clue why it would go wrong on a different linux system. That seems unlikely somehow. Perhaps the data you feed into SimpleCrypt is corrupted somehow?

• Yes, sorry something else went wrong on those systems and indeed corrupted the settings string.

SimpleCrypt works perfectly.

• Hi,

[quote author="Andre" date="1300457411"]I have just added a "page":http://developer.qt.nokia.com/wiki/Simple_encryption in the Snippets category [/quote]

Thanks for this class. I am invoking it's constructor with my predefined key (my secret) and I am wondering why qsrand() is initialized with currentTimeMillis or similar (in the constructor code)? I don't get the same encryption results on multiple invocations so I used my quint64 key to initialize qsrand (in the constructor), then it works..

@

qDebug() << "Crypt1 " << c1.encryptToString(QString("justatest"));
qDebug() << "Crypt2 " << c2.encryptToString(QString("justatest"));
@

Output
@
Crypt1 "AwLLXV+ZSO+x3Ise1Aw="
Crypt2 "AwIUgoBGlzBuA1TBC9M="
@

Just wondering :)

• Why would you want to have the same cypher text when using the same clear text and key? As long as the decrypted plain text from these cypher texts is the same, what is the problem with having different cypher texts? The algorithm uses a randomization of the string on purpose. It makes it much harder to leak part of the key because analysis is much harder this way.

An explanation is in the "details page":/wiki/SimpleCrypt_algorithm_details#2d478ba9ee3cf03e338b506b1a0292dc that has more on the idea of using a random number as a leading byte.

You replacing that they way you did partly negates this, and thus makes the cypher weaker by a couple of bits. Note that even with your change, encrypting the same plain text using the same SimpleCrypt instance twice will result in different cypher texts.

• Hi Andre,

Thanks for answering; I wasn't looking for reasonably strong encryption - I just wanted to always get the same encrypted string for the same input (private key+string_to_be_encrypted); its just for private use anyway, and non-critical.

I am using QCryptographicHash for that now, it solves my problem

• Eh, no, that class does not solve your problem, if you are indeed looking for encryption rather than hashing. There is a big difference between the two...

• [quote author="Andre" date="1356878054"]Eh, no, that class does not solve your problem, if you are indeed looking for encryption rather than hashing. There is a big difference between the two... [/quote]

That's a chicken and egg problem: I don't want to elaborate on "my problem" and hence prove that I am fine with hashing because of concerns of privacy. Please understand that and thank you for your help.

• worked in QT 5?

@//QString cypherString = QString::fromAscii(cypher.toBase64());
QString cypherString = QString::fromUtf8(cypher.toBase64());

//QString cypherString = QString::fromAscii(cypher.toBase64());
QString cypherString = QString::fromUtf8(cypher.toBase64());

//QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toAscii());
QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toUtf8());

//QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toAscii());
QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toUtf8());@

there will be well done this.

• I was getting SIGABRT's when attempting to decrypt an empty string with a Qt with debugging enabled. So I've added a little check. Doesn't seem possible to link to wiki history diffs, but you can see it there.

• Thanks, good catch.

@
if( cypher.count() < 3 )
return QByteArray();
@

A small problem is, that no error code is set. I think that needs to be added.

• good, and in QT5 probe, and all good the only thing that was included # include <QDataStream>, and change QString :: fromutf8 () and QString :: toutf8 ().

Clearly only tried with 30 words, and it has worked well.

• Hi Andre,

thanks for sharing this very useful code. Works perfectly, did save me quite some time. May I buy you a beer on next DevDays?

Nils

• [quote author="njeisecke" date="1362060748"]Hi Andre,

thanks for sharing this very useful code. Works perfectly, did save me quite some time. May I buy you a beer on next DevDays?

Nils[/quote]
Good to hear that. If I'm able to go, you most certainly are welcome to buy me one :-)

• Hi,

I'm having some troubles using your code.
For the same binary the encryption/decryption of the string using a key works fine.
But if i change the source code and add something like: qWarning() << "what you want";

Is this a normal behavior ??

• Well, no, of course not. However, your description is so vague that I have no idea what could be wrong.

• Hi,

I was using a stupid generated test key like: quint64 key( qHash( "the_test_key" ) );
When the binary change, the hash returned by this call was not identical as previously, resulting to badly decrypted content.
Using QString version fixed the problem: quint64 key( qHash( QString( "the_test_key" ) ) );

thanks you!

• I don't think qHash is guaranteed to give the same result between runs actually, so it seems unwise to me to use it in this way. Furthermore, it is not very secure. qHash returns a uint, while the key used is a quint64. So, you are only using a 32 bits key instead of a 64 bits one.

• Right, it's not secure, as i told, it was a test project.
The problem of the qHash over a const char* is that it may be done differently depending the os / compiler.
A qHash around a QString is always giving the same result because it hash the string content - I did not read the code on what it does with const char*.
Anyway, yes using this way is not a good way, but it was a test.
By the way is there some repository to to track the code ? having to copy/paste it from a wiki page is not so natural.

Thanks for your code, and the help.

• No the code is not in a repo, but I probably should put it on Gitorious or something like that.

For generating a key out of a string, I think I'd just use QCryptographic hash with MD5 or SHA-1, and create a 64 bit key out of the 16 (MD5) or 20 (SHA-1) bytes these generate. The key you need is 8 bytes, but reducing the 16 or 20 bytes to 8 is just a simple XOR or two away...

• Hey there, I am new to Qt and just came across your work ... great work by the way... could you tell me where your updated work might be? like the latest one?

cuz I seem to have a problem with this one - https://www.gitorious.org/qtdevnet-wiki-mvc/qtdevnet-simplecryptiodevide/source/a170750960820be4230ea1aff85148fc41f0dcf3:

• Hi Andre,

Thanks for the code. It is really useful.

But is there any way to find out whether the file is encrypted or not? I would like to know if the input file is encrypted or not, if yes, then only I will decrypt it.

Vrushali

• Hi Andre,
an example how to check it You got directly in the code:

@
if (version !=3) { //we only work with version 3
m_lastError = ErrorUnknownVersion;
qWarning() << "Invalid version or not a cyphertext.";
return QByteArray();
}
@

But is very useful thing that if You send to decryp function non-encypted data it will return the same string.

• Hi Andre,
an example how to check it You got directly in the code:

@
if (version !=3) { //we only work with version 3
m_lastError = ErrorUnknownVersion;
qWarning() << "Invalid version or not a cyphertext.";
return QByteArray();
}
@

But is very useful thing that if You send to decryp function non-encypted data it will return the same string.

• I disagree. I don't think the class should return the cyphertext as the plaintext if the cyphertext could not be decrypted. I think that it is the responsibility of the application to keep the conceptually very different plaintext and cypher text separate. If you don't know if a text is a cyphertext or a plaintext, I think you have design issues.

If you really want, you can work around this yourself by simply checking the returned string and the last error, and then using the original plain text on decryption error. I wouldn't recommend that though.

• I disagree. I don't think the class should return the cyphertext as the plaintext if the cyphertext could not be decrypted. I think that it is the responsibility of the application to keep the conceptually very different plaintext and cypher text separate. If you don't know if a text is a cyphertext or a plaintext, I think you have design issues.

If you really want, you can work around this yourself by simply checking the returned string and the last error, and then using the original plain text on decryption error. I wouldn't recommend that though.

• I could have this situation only when im switching between debug/release mode, because I decidated not to enrypt files when Im working on debug mode, thus when I go back to release all my files are not encrypted. At the moment I check result, and if its empty I put the orginal string.

• I could have this situation only when im switching between debug/release mode, because I decidated not to enrypt files when Im working on debug mode, thus when I go back to release all my files are not encrypted. At the moment I check result, and if its empty I put the orginal string.

• One more question to the author I changed all calls of depraced from and to ASCII to Latin1 not to Utf8. It's ok with that?

• One more question to the author I changed all calls of depraced from and to ASCII to Latin1 not to Utf8. It's ok with that?

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