Simple encryption: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
 
(14 intermediate revisions by 5 users not shown)
Line 1: Line 1:
=Simple encryption with SimpleCrypt=
#REDIRECT [[Simple encryption with SimpleCrypt]]
 
Sometimes, you have to store some information that you may want to protect against casual observation. Think about passwords for remote services, for instance. Strong cryptography is obviously the best solution, but it can be hard to use those in the right way, they tend to pull in more libraries, and frankly, it may just be overkill for the situation.
 
* Note: additional details are available in [[SimpleCrypt algorithm details|SimpleCrypt_algorithm_details]]
* Note: a usage example can be found here [[Simple Crypt IO Device|Simple_Crypt_IO_Device]]
 
==A word of warning==
 
====The class presented in this article does ''not'' provide strong encryption!====
 
It will protect your data from casual observers, but it will not stand up to dedicated hackers trying to break your secrets. I am not a cryptography expert. Use the code here at your own risk. I am not to be held responsible for any damages that may, directly or indirectly, happen because of your use of this code. Don’t say you were not warned.
 
==Introducing SimpleCrypt==
 
The idea of <code>SimpleCrypt</code> is to provide some basic cryptographic capabilities for simple encryption. Only symmetric encryption is supported (that is: only with the same key for encryption and decryption), and there is no <span class="caps">API</span> for streaming data in and out like you often see with more advanced cyphers. If you need stronger cryptography, streaming cyphers or asymmetric keys, take a look at [http://delta.affinix.com/qca/ <span class="caps">QCA</span>] ''[delta.affinix.com]'' instead.
 
The <code>SimpleCrypt</code> class takes a 64 bits key in the form of a quint64. If you use a fixed key build into your program, you can do something like this to initialize your <code>SimpleCrypt</code> object:
 
You can also use the <code>setKey()</code> method to set a key on the class.
 
===Selecting a suitable key===
 
To get such random numbers, you might use [http://www.random.org/integers/?num=10&min=0&max=65535&col=5&base=16&format=html&rnd=new this service] ''[random.org]'' and pick four of the 2 byte hexadecimals that you concatenate together as done above. That works better than trying to make up something semi-random yourself. Of course, you can also use other means to get to a quint64 key, such as using some hash of a password and reducing that to 64 bits.
 
===SimpleCrypt in use===
 
Once setup, you can use <code>SimpleCrypt</code> to actually encrypt or decrypt data. For the encrypt functions, both the ''plaintext'' that you input as the ''cyphertext'' that is being outputted can be either a <code>QString</code> or a <code>QByteArray</code>. The reverse applies to the decrypt functions. That results in four encrypt methods, and four corresponding decrypt methods:
 
=====Encryption methods=====
 
* <code>QString encryptToString(const QString&amp; plaintext)</code>
* <code>QString encryptToString(QByteArray plaintext)</code>
* <code>QByteArray encryptToByteArray(const QString&amp; plaintext)</code>
* <code>QByteArray encryptToByteArray(QByteArray plaintext)</code>
 
=====Decryption methods=====
 
* <code>QString decryptToString(const QString&amp; plaintext)</code>
* <code>QString decryptToString(QByteArray plaintext)</code>
* <code>QByteArray decryptToByteArray(const QString&amp; plaintext)</code>
* <code>QByteArray decryptToByteArray(QByteArray plaintext)</code>
 
====Use with QStrings====
 
The code above encrypts a <code>QString</code> to a <code>QString</code>, and then decrypts that string again to a new <code>QString</code>.
 
====Use with binary data====
 
If you want to encrypt your own binary data, you might do something like this:
 
Note the use of the data protection feature. I would recommend that you use at least the <code>ProtectionChecksum</code> level of protection (enabled by default) if you work with binary data, as streaming invalid binary data into your program can lead to big problems.
 
On the other end, you can now do:<br />
 
The code above might crash if the integrity of the data is not guaranteed, for instance by the use of a wrong password. Using the highest level of protection is probably OK here, as we have quite a big blob of data already, so adding the overhead of adding a 20 byte SHA1 cryptographic hash is justifiable.
 
==Compression==
 
For long strings, it can be beneficial to use compression before encryption. Not only does the length of the string decrease, the input will be a bit more random-looking too, resulting in a harder to break cyphertext (at least, in principle, see the warning at the top of this page.) However, for short strings, applying compression can lead to an ''increase'' in the string length.
 
<code>SimpleCrypt</code> supports three modes for compression before encryption. You can force to always use compression, to never use compression, or to automatically choose the shortest version (either the compressed one or the uncompressed one). The last option is the default option. Note that setting this only affects ''encryption''. For decryption, <code>SimpleCrypt</code> automatically decompresses the data if compression was used for the encryption.
 
==The code==
 
simplecrypt.h<br />
 
simplecrypt.cpp<br />
 
You can copy/paste the code above into your own simplecrypt.h and simplecrypt.cpp files to use it.
 
==Details on the algorithm==
 
The algorithm and data format used in this class, have been detailed on a [[SimpleCrypt algorithm details|separate page]]. On that page, you can find byte-for-byte descriptions of how the cypher text is constructed from the plain text.
 
==Future extensions==
 
I, or somebody else, may choose to extend <code>SimpleCrypt</code> in the future, or fix a weakness of some kind. To make that possible without loosing the option to read your older encrypted data, the generated cyphertext contains a version number. The idea is that future versions of this code will have a higher version number, but will keep supporting the decryption of cyphertexts with a lower version number. The current version number is 2. Note that these version numbers need not coincide with code version numbers, as a change in the code does not always result in a change in the actual encryption.
 
==Versions==
 
The current code is version 3 of the code.
 
====Version 3====
 
* Fixed embarrassing mistake with only using 4 out of 8 of the key bytes. Thanks to Gerolf for noticing!
 
====Version 2====
 
* Renamed flags to avoid clashes
* Upped version number to 2, but did not retain backwards comparability
* Added optional data integrity protection using either a checksum or a cryptographic hash
* Added error reporting (making is necessary to make the encryption and decryption functions non-const)
 
====Version 1====
 
This marks the first public release.
 
==Feedback==
 
I would really welcome feedback on this class, both on the <span class="caps">API</span> and on the crypto algorithm itself. If you spot big weaknesses, please let me know. This class is meant for simple encryption needs, but that does not mean that we need to leave gaping security holes in the code, of course. Please use [http://developer.qt.nokia.com/forums/viewthread/4565 this forum topic] ''[developer.qt.nokia.com]'' for feedback.
 
===Categories:===
 
* [[:Category:snippets|snippets]]

Latest revision as of 10:30, 16 June 2015