📜 ⬆️ ⬇️

Simple implementation of encrypting and decrypting files in Qt

Greetings, respectable habrasoobschestvu.

Recently faced with the need to encrypt and decrypt files in a Qt project. The main condition is simplicity and transparency, since, in fact, you need to replace the work with files through QFile with something that can write data in encrypted form and read them from an encrypted file. As a result, a small class was born. Then there was a desire to share it with the public, maybe someone will come in handy and save time, and maybe someone will refine it and change life for the better.

The main point, as I said, was simple and transparent work with the class. Those. the class must be able to write the data immediately in encrypted form, as well as read the source data from the encrypted file.

The one who is already familiar with Qt, and in particular with QIODevice , knows what a powerful tool for working with input-output devices. Therefore, almost immediately it was decided to take this class as a basis and inherit from it. I will not dwell on this point in detail, just to note that the main “magic” is to redefine the methods.
qint64 QIODevice::writeData(const char *data, qint64 len) 
and
 qint64 QIODevice::readData(char *data, qint64 len) 
respectively for writing data and reading.
')
To indicate which file to work with, the class user has several ways:
1) Pass the file path
2) Pass a pointer to a QFileDevice object.

If you are wondering why QFileDevice, and not QFile, then the answer is simple. That it was possible to transfer such useful class as QSaveFile .

After that, the actual question became, which tool should be used directly to encrypt and decrypt data? After a brief study, it was decided to stop at the OpenSSL library because, first, it is one of the leaders in the data encryption world, and second, our project has already used this library for other tasks.

Therefore, when choosing an encryption algorithm, it was decided to use a symmetric algorithm, since It allows you to quickly encrypt data in blocks. An important requirement for the class being implemented was the ability to write to a file from any location. In this regard, it was necessary to bear in mind that the encrypted data did not depend on previous or subsequent data. In light of all the limitations, it was decided to choose the AES algorithm with ECB mode (see update). This mode allows you to get the independence of a specific data block from the rest, however, the level of security of course falls. Had to come to terms with this. It is worth noting that now the user can choose the key bit of 128, 192 or 256 bits (the lower the bit, the faster the algorithm works, but it becomes less secure). For encryption using OpenSSL, high-level EVP encryption methods were used .

During the implementation of the class, an idea came up to make a certain header for the encrypted file and store some necessary things, such as a password hash and salt, to control their accuracy when opening the file. Naturally, in any case, with the wrong password and salt, the user will not be able to read the file normally, but we decided to check this at the moment of opening the file, so that the user was sure that if he opened the correctly encrypted file, it will work with the correct input data.

Of the interesting points, it is worth noting that the class can work with regular files. If you do not specify a password, then we will work with the file also as if working with a regular QFile.

To understand how to work with the class, I made two test projects.
The first project involves performing basic file operations. For comparison, the QFile class object is used, the results of which are checked with the developed class.
The second project shows how it is useful to organize work with encrypted files for the end user. The project implements encryption of the image selected by the user and its subsequent display in QWebView — the file is encrypted, but the user sees the original image.

Using a class is very simple - copy 2 files (cryptfiledevice.cpp and cryptfiledevice.h) into your project and you can already work with it.

Dependencies at the moment:
1) Qt> = 5.1.0 (since SHA3 is used for the password hash and salt)
2) Compiler supporting c ++ 11

The class and test projects were tested on Windows 7 (x86, x64), Ubuntu (x64) and MacOS X Mavericks.

There are still some thoughts that I would like to realize in the future. This is the implementation of the methods remove, rename, exists, by analogy with QFile, in order not to include QFile if it is not necessary. Also, I would like to add a method that allows the user to determine whether this file is encrypted or not. I hope that in the near future my hands will reach, and I will add this functionality.
Plus, you can think about working with other algorithms.

Sources laid out in open access on GitHub under the MIT license. Take, use, improve on health. You can send all offers and wishes to email or write to the issue tracker (all information is in the README on GitHub).

GitHub Link: CryptFileDevice

Update

Thanks to all who are not indifferent, I did not expect that there will be a lot of feedback with suggestions and wishes.
I tried to take into account the opinion of the majority.
Changed AES-ECB to AES-CTR, thereby increasing encryption security (thanks to Disasm ).
All fixes are uploaded to github .

Source: https://habr.com/ru/post/240051/


All Articles