...

суббота, 14 сентября 2013 г.

Шифруемся в Qt

Так как оказалось, что наши коммуникации довольно легко просматриваются товарищами из АНБ то похоже что нужно шифровать все коммуникации. Я решил проверить насколько сложно подключить шифрование в разработке Qt приложений. Как оказалось что все совсем несложно даже в случае использовании PGP.

Так что тут больше дело привычки разработчика чтобы шифровать критические данные.


Вот и попробуем использовать PGP в нашем простом примере. Конечно уже существует отличный framework QCA (http://delta.affinix.com/qca/) который сделает все за нас. Нам только разобраться с правильным использованием QCA.


Создадим простое десктопное пролижение которое может зашифровать входной текст. Предполагается что у нас уже установлен GnuPG, сгенерированны ключики, получены ключики получателя, установлен и отконфигурирован gpg-agent, установлен и проверен pinentry-qt/pinentry-gtk(дада, мы на линуксе). Затем нам нужно установить qca и qca-gnupg


emerge --ask qca qca-gnupg


Запустим Qt Creator, выберем Qt Gui application, добавим туда qca:



LIBS += -L/usr/lib/qca2 -lqca
INCLUDEPATH += /usr/include/qca2/QtCrypto



Создадим простую форму, соединим кнопку с нашим слотом «encrypt»:



В main.cpp все что нам нужно это инициализация QtCrypt:

#include <QtCrypto>
#include <QApplication>
#include "CryptWin.h"
int main(int argc, char *argv[]) {
QCA::Initializer init;
QApplication a(argc, argv);
CryptWindow w;
w.show();
return a.exec();
}

Затем в конструкторе окна получим список всех доступных ключиков чтобы инициализировать комбобоксы:



QCA::KeyStoreManager::start();
QCA::KeyStoreManager ksm(this);
ksm.waitForBusyFinished();

QCA::KeyStore pgpks( QString("qca-gnupg"), &ksm );

foreach(const QCA::KeyStoreEntry kse, pgpks.entryList()) {
QString text = kse.name()+" "+kse.id();
QVariant v; v.setValue(kse);
ui->cb_to->addItem(text, v);
if (!kse.pgpSecretKey().isNull())
ui->cb_my->addItem(text, v);
}



Первый(верхний) комбобокс получит все ключики которые имеют секретную часть — отправитель, второй(нижний) комбобокс получит все ключики у которых есть публичная часть — получатель. Сами ключики встроим в элементы комбобокса используя QVariant data аргумент вызова addItem()

Осталось написать только слот для «Encrypt» кнопки:



void CryptWindow::encrypt() {
QVariant v_my = ui->cb_my->itemData(ui->cb_my->currentIndex());
QVariant v_to = ui->cb_to->itemData(ui->cb_to->currentIndex());
if (!v_my.isValid()) { ui->pte_dst->setPlainText("Invalid src"); return; }
if (!v_to.isValid()) { ui->pte_dst->setPlainText("Invalid dst"); return; }
QCA::KeyStoreEntry kse_my = v_my.value<QCA::KeyStoreEntry>();
QCA::KeyStoreEntry kse_to = v_to.value<QCA::KeyStoreEntry>();

QCA::SecureMessageKey to;
to.setPGPSecretKey( kse_my.pgpSecretKey() );
to.setPGPPublicKey( kse_to.pgpPublicKey() );

QCA::OpenPGP pgp;
QCA::SecureMessage msg(&pgp);

msg.setRecipient(to);
msg.setFormat(QCA::SecureMessage::Ascii);
msg.startEncrypt();
msg.update(ui->pte_src->toPlainText().toUtf8());
msg.end();
msg.waitForFinished(2000);

QByteArray crpt = msg.read();
ui->pte_dst->setPlainText(QString::fromUtf8(crpt));
}



Попробуем запустить и протестировать наше приложение (кстати через gpg-agent оно спросит пароль выбранного секретного ключа, поэтому важно проверить сначала работу pinentry):


Довольно просто, не так ли? Шифруемся!


(английский вариант со всеми исходниками приложения: lynxline.com/qt-and-use-of-cryptography-simple/)


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends:



Комментариев нет:

Отправить комментарий