New SimpleCrypt page
-
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 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.
- copy + paste + compile
-
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).
-
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.