Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.

Simple encryption

From Qt Wiki
Revision as of 17:46, 14 January 2015 by Maintenance script (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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.

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

SimpleCrypt

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 API 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 QCA [delta.affinix.com] instead. The

SimpleCrypt

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

SimpleCrypt

object: You can also use the

setKey()

method to set a key on the class.

Selecting a suitable key

To get such random numbers, you might use 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

SimpleCrypt

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

QString

or a

QByteArray

. The reverse applies to the decrypt functions. That results in four encrypt methods, and four corresponding decrypt methods:

Encryption methods
  • QString encryptToString(const QString& plaintext)
    
  • QString encryptToString(QByteArray plaintext)
    
  • QByteArray encryptToByteArray(const QString& plaintext)
    
  • QByteArray encryptToByteArray(QByteArray plaintext)
    
Decryption methods
  • QString decryptToString(const QString& plaintext)
    
  • QString decryptToString(QByteArray plaintext)
    
  • QByteArray decryptToByteArray(const QString& plaintext)
    
  • QByteArray decryptToByteArray(QByteArray plaintext)
    

Use with QStrings

The code above encrypts a

QString

to a

QString

, and then decrypts that string again to a new

QString

.

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

ProtectionChecksum

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:

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.

SimpleCrypt

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,

SimpleCrypt

automatically decompresses the data if compression was used for the encryption.

The code

simplecrypt.h

simplecrypt.cpp

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 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

SimpleCrypt

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 API 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 this forum topic [developer.qt.nokia.com] for feedback.

Categories: