Ecnryptable note
This commit is contained in:
@@ -71,7 +71,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Version 1.1.0.0</string>
|
||||
<string>Version 1.2.0.0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
|
||||
@@ -14,6 +14,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
connect(ui->noteList, &QListWidget::currentRowChanged, this, &MainWindow::selectionChanged);
|
||||
connect(ui->titleEdit, &QLineEdit::textChanged, this, &MainWindow::titleChanged);
|
||||
connect(ui->contentEdit, &QPlainTextEdit::textChanged, this, &MainWindow::contentChanged);
|
||||
connect(ui->actionEncrypt, &QAction::triggered, this, &MainWindow::encryptNote);
|
||||
const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
||||
ui->contentEdit->setFont(fixedFont);
|
||||
this->savemng = new SaveManager();
|
||||
@@ -55,8 +56,13 @@ void MainWindow::selectionChanged(int i)
|
||||
ui->titleEdit->setDisabled(false);
|
||||
ui->contentEdit->setDisabled(false);
|
||||
ui->titleEdit->setText(n->getTitle());
|
||||
ui->contentEdit->setPlainText(n->getContent());
|
||||
ui->markdownViewer->setMarkdown(n->getContent());
|
||||
if (n->isEncrypted())
|
||||
{
|
||||
ui->contentEdit->setPlainText(n->getEncryptedContent("azertyuiop"));
|
||||
} else {
|
||||
ui->contentEdit->setPlainText(n->getContent());
|
||||
}
|
||||
ui->markdownViewer->setMarkdown(ui->contentEdit->toPlainText());
|
||||
}
|
||||
|
||||
void MainWindow::removeSelected()
|
||||
@@ -71,6 +77,7 @@ void MainWindow::removeSelected()
|
||||
|
||||
void MainWindow::save()
|
||||
{
|
||||
ui->actionSave->setDisabled(true);
|
||||
if (this->currentIndex > -1)
|
||||
{
|
||||
Note *n = this->savemng->getNoteByIndex(this->currentIndex);
|
||||
@@ -89,6 +96,7 @@ void MainWindow::titleChanged()
|
||||
n->setTitle(ui->titleEdit->text());
|
||||
ui->noteList->item(this->currentIndex)->setText(ui->titleEdit->text());
|
||||
}
|
||||
ui->actionSave->setDisabled(false);
|
||||
timer->start(1000);
|
||||
}
|
||||
|
||||
@@ -99,6 +107,16 @@ void MainWindow::showAboutBox()
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void MainWindow::encryptNote()
|
||||
{
|
||||
if (this->currentIndex > -1)
|
||||
{
|
||||
Note *n = this->savemng->getNoteByIndex(this->currentIndex);
|
||||
n->encrypt("azertyuiop");
|
||||
savemng->flushSave();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::contentChanged()
|
||||
{
|
||||
timer->stop();
|
||||
@@ -108,6 +126,7 @@ void MainWindow::contentChanged()
|
||||
n->setContent(ui->contentEdit->toPlainText());
|
||||
ui->markdownViewer->setMarkdown(ui->contentEdit->toPlainText());
|
||||
}
|
||||
ui->actionSave->setDisabled(false);
|
||||
timer->start(1000);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ private slots:
|
||||
void contentChanged();
|
||||
void titleChanged();
|
||||
void showAboutBox();
|
||||
void encryptNote();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
|
||||
@@ -120,15 +120,24 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>33</height>
|
||||
<height>96</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextUnderIcon</enum>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
@@ -140,12 +149,16 @@
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSave"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionLock"/>
|
||||
<addaction name="actionUnlock"/>
|
||||
<addaction name="actionEncrypt"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionAbout"/>
|
||||
</widget>
|
||||
<action name="actionAdd">
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons.qrc">
|
||||
<normaloff>:/icon/resources/outline_add_circle_outline_black_18dp.png</normaloff>:/icon/resources/outline_add_circle_outline_black_18dp.png</iconset>
|
||||
<normaloff>:/icon/resources/outline_add_circle_outline_black_48dp.png</normaloff>:/icon/resources/outline_add_circle_outline_black_48dp.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
@@ -157,16 +170,19 @@
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons.qrc">
|
||||
<normaloff>:/icon/resources/outline_delete_forever_black_18dp.png</normaloff>:/icon/resources/outline_delete_forever_black_18dp.png</iconset>
|
||||
<normaloff>:/icon/resources/outline_delete_forever_black_48dp.png</normaloff>:/icon/resources/outline_delete_forever_black_48dp.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons.qrc">
|
||||
<normaloff>:/icon/resources/outline_save_black_18dp.png</normaloff>:/icon/resources/outline_save_black_18dp.png</iconset>
|
||||
<normaloff>:/icon/resources/outline_save_black_48dp.png</normaloff>:/icon/resources/outline_save_black_48dp.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
@@ -175,12 +191,45 @@
|
||||
<action name="actionAbout">
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons.qrc">
|
||||
<normaloff>:/icon/resources/outline_help_outline_black_18dp.png</normaloff>:/icon/resources/outline_help_outline_black_18dp.png</iconset>
|
||||
<normaloff>:/icon/resources/outline_help_outline_black_48dp.png</normaloff>:/icon/resources/outline_help_outline_black_48dp.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>About</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLock">
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons.qrc">
|
||||
<normaloff>:/icon/resources/outline_lock_black_48dp.png</normaloff>:/icon/resources/outline_lock_black_48dp.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Lock</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUnlock">
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons.qrc">
|
||||
<normaloff>:/icon/resources/outline_lock_open_black_48dp.png</normaloff>:/icon/resources/outline_lock_open_black_48dp.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unlock</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEncrypt">
|
||||
<property name="icon">
|
||||
<iconset resource="../../icons.qrc">
|
||||
<normaloff>:/icon/resources/outline_shield_black_48dp.png</normaloff>:/icon/resources/outline_shield_black_48dp.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Encrypt</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../icons.qrc"/>
|
||||
|
||||
@@ -2,27 +2,35 @@
|
||||
|
||||
Note::Note()
|
||||
{
|
||||
|
||||
QUuid uid = QUuid::createUuid();
|
||||
this->uuid = uid.toString(QUuid::StringFormat::WithoutBraces);
|
||||
}
|
||||
|
||||
QJsonObject Note::toJson()
|
||||
{
|
||||
QJsonObject o;
|
||||
|
||||
o["uuid"] = this->uuid;
|
||||
o["title"] = this->title;
|
||||
o["content"] = this->content;
|
||||
|
||||
o["encrypted"] = this->encrypted;
|
||||
return o;
|
||||
}
|
||||
|
||||
Note *Note::fromJson(QJsonObject o)
|
||||
{
|
||||
Note *n = new Note();
|
||||
n->uuid = o["uuid"].toString(n->uuid);
|
||||
n->title = o["title"].toString();
|
||||
n->content = o["content"].toString();
|
||||
n->encrypted = o["encrypted"].toBool(false);
|
||||
return n;
|
||||
}
|
||||
|
||||
QString Note::getUuid()
|
||||
{
|
||||
return uuid;
|
||||
}
|
||||
|
||||
QString Note::getTitle()
|
||||
{
|
||||
return title;
|
||||
@@ -30,7 +38,47 @@ QString Note::getTitle()
|
||||
|
||||
QString Note::getContent()
|
||||
{
|
||||
return content;
|
||||
if (!this->encrypted)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
QString Note::getEncryptedContent(QString passwd)
|
||||
{
|
||||
if (this->encrypted)
|
||||
{
|
||||
using namespace CryptoPP;
|
||||
std::string password = passwd.toStdString();
|
||||
QString bytes = QByteArray::fromBase64(QByteArray::fromStdString(this->content.toStdString()));
|
||||
std::string encoded = bytes.toStdString();
|
||||
std::string iv = encoded.substr(0, TAG_SIZE);
|
||||
std::string cipher = encoded.substr(TAG_SIZE + 1, encoded.length());
|
||||
std::string recovered;
|
||||
|
||||
try {
|
||||
GCM< AES >::Decryption d;
|
||||
d.SetKeyWithIV((const unsigned char*)password.c_str(), sizeof(password.c_str()), (const unsigned char*)iv.c_str(), sizeof(iv.c_str()));
|
||||
|
||||
AuthenticatedDecryptionFilter df( d,
|
||||
new StringSink(recovered),
|
||||
AuthenticatedDecryptionFilter::DEFAULT_FLAGS, TAG_SIZE
|
||||
);
|
||||
StringSource ss2(cipher, true,
|
||||
new Redirector(df)
|
||||
);
|
||||
return QString::fromStdString(recovered);
|
||||
} catch (CryptoPP::Exception& e) {
|
||||
std::cout << e.GetWhat() << "\n";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Note::isEncrypted()
|
||||
{
|
||||
return this->encrypted;
|
||||
}
|
||||
|
||||
void Note::setTitle(QString value)
|
||||
@@ -40,6 +88,57 @@ void Note::setTitle(QString value)
|
||||
|
||||
void Note::setContent(QString value)
|
||||
{
|
||||
if (!this->encrypted) {
|
||||
this->content = value;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO encrypt avec le mot de passe
|
||||
bool Note::setEncryptedContent(QString value, QString passwd)
|
||||
{
|
||||
if (this->encrypted) {
|
||||
using namespace CryptoPP;
|
||||
AutoSeededRandomPool prng;
|
||||
std::string password = passwd.toStdString();
|
||||
std::string pdata = value.toStdString();
|
||||
std::string cipher, encoded;
|
||||
|
||||
SecByteBlock key(AES::MAX_KEYLENGTH + AES::BLOCKSIZE);
|
||||
SecByteBlock iv(AES::BLOCKSIZE);
|
||||
prng.GenerateBlock(iv, iv.size());
|
||||
try
|
||||
{
|
||||
GCM<AES>::Encryption e;
|
||||
e.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
|
||||
|
||||
StringSource ss1(pdata, true,
|
||||
new AuthenticatedEncryptionFilter(e,
|
||||
new StringSink(cipher), false, TAG_SIZE
|
||||
)
|
||||
);
|
||||
std::string s(reinterpret_cast< char const* >(iv.data())) ;
|
||||
encoded = s + cipher;
|
||||
auto bytes = QByteArray::fromStdString(encoded);
|
||||
this->content = bytes.toBase64();
|
||||
return true;
|
||||
}
|
||||
catch(CryptoPP::Exception& e)
|
||||
{
|
||||
std::cout << e.GetWhat() << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Note::encrypt(QString password)
|
||||
{
|
||||
if (!this->encrypted && (password.length() >= 6)) {
|
||||
this->encrypted = true;
|
||||
if (!setEncryptedContent(this->content, password))
|
||||
{
|
||||
this->encrypted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,25 @@
|
||||
#ifndef NOTE_H
|
||||
#define NOTE_H
|
||||
|
||||
#define TAG_SIZE 12
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
#include <QUuid>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <crypto++/modes.h>
|
||||
#include <crypto++/aes.h>
|
||||
#include <crypto++/filters.h>
|
||||
#include <crypto++/cryptlib.h>
|
||||
#include <crypto++/sha.h>
|
||||
#include <crypto++/hkdf.h>
|
||||
#include <crypto++/osrng.h>
|
||||
#include <crypto++/gcm.h>
|
||||
#include <crypto++/rijndael.h>
|
||||
|
||||
class Note
|
||||
{
|
||||
@@ -12,15 +29,23 @@ public:
|
||||
QJsonObject toJson();
|
||||
static Note* fromJson(QJsonObject o);
|
||||
|
||||
QString getUuid();
|
||||
QString getTitle();
|
||||
QString getContent();
|
||||
QString getEncryptedContent(QString passwd);
|
||||
bool isEncrypted();
|
||||
|
||||
void setTitle(QString value);
|
||||
void setContent(QString value);
|
||||
bool setEncryptedContent(QString value, QString passwd);
|
||||
|
||||
void encrypt(QString password);
|
||||
|
||||
private:
|
||||
QString uuid;
|
||||
QString title;
|
||||
QString content;
|
||||
bool encrypted;
|
||||
};
|
||||
|
||||
#endif // NOTE_H
|
||||
|
||||
@@ -8,6 +8,10 @@ SaveManager::SaveManager()
|
||||
SaveManager::~SaveManager()
|
||||
{
|
||||
flushSave();
|
||||
foreach (Note *n, notes)
|
||||
{
|
||||
delete n;
|
||||
}
|
||||
}
|
||||
|
||||
void SaveManager::flushSave()
|
||||
|
||||
Reference in New Issue
Block a user