mirror of
https://github.com/kingToolbox/WindTerm.git
synced 2025-01-29 06:40:31 +08:00
Add a safe encryption class.
This commit is contained in:
parent
516b5aaa1f
commit
479b939b54
91
src/Cryptographic.cpp
Normal file
91
src/Cryptographic.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2020, WindTerm.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "Cryptographic.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <qpassworddigestor.h>
|
||||
#include <QRandomGenerator>
|
||||
|
||||
#include "openssl/evp.h"
|
||||
|
||||
constexpr int AES_256_IV_LENGTH = 16;
|
||||
constexpr int AES_256_KEY_LENGTH = 32;
|
||||
constexpr int PBKDF2_LENGTH = AES_256_IV_LENGTH + AES_256_KEY_LENGTH;
|
||||
constexpr int PBKDF2_ITERATION_COUNT = 100000;
|
||||
|
||||
QByteArray Cryptographic::decrypt(const QByteArray &data, const QByteArray &pbkdf2) {
|
||||
return doCrypt(QByteArray::fromBase64(data), Cryptographic::key(pbkdf2), Cryptographic::iv(pbkdf2), 0);
|
||||
}
|
||||
|
||||
QByteArray Cryptographic::doCrypt(QByteArray data, const QByteArray &key, const QByteArray &iv, int enc) {
|
||||
QByteArray crypted(data.length() + EVP_MAX_BLOCK_LENGTH, '\0');
|
||||
int cryptedLength = 0;
|
||||
int length;
|
||||
|
||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||
|
||||
EVP_CipherInit_ex(
|
||||
ctx,
|
||||
EVP_aes_256_cbc(),
|
||||
nullptr,
|
||||
reinterpret_cast<const uchar *>(key.constData()),
|
||||
reinterpret_cast<const uchar *>(iv.constData()),
|
||||
enc
|
||||
);
|
||||
|
||||
EVP_CipherUpdate(
|
||||
ctx,
|
||||
reinterpret_cast<uchar *>(crypted.data()),
|
||||
&length,
|
||||
reinterpret_cast<const uchar *>(data.constData()),
|
||||
data.length()
|
||||
);
|
||||
cryptedLength += length;
|
||||
|
||||
EVP_CipherFinal_ex(ctx, reinterpret_cast<uchar *>(crypted.data() + cryptedLength), &length);
|
||||
cryptedLength += length;
|
||||
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
crypted.resize(cryptedLength);
|
||||
return crypted;
|
||||
}
|
||||
|
||||
QByteArray Cryptographic::encrypt(const QByteArray &data, const QByteArray &pbkdf2) {
|
||||
QByteArray encrypted = doCrypt(data, Cryptographic::key(pbkdf2), Cryptographic::iv(pbkdf2), 1);
|
||||
return encrypted.toBase64();
|
||||
}
|
||||
|
||||
QByteArray Cryptographic::iv(const QByteArray &pbkdf2) {
|
||||
Q_ASSERT(pbkdf2.length() == PBKDF2_LENGTH);
|
||||
return QByteArray::fromRawData(pbkdf2.constData() + AES_256_KEY_LENGTH, AES_256_IV_LENGTH);
|
||||
}
|
||||
|
||||
QByteArray Cryptographic::key(const QByteArray &pbkdf2) {
|
||||
Q_ASSERT(pbkdf2.length() == PBKDF2_LENGTH);
|
||||
return QByteArray::fromRawData(pbkdf2.constData(), AES_256_KEY_LENGTH);
|
||||
}
|
||||
|
||||
QByteArray Cryptographic::pbkdf2(const QByteArray &password, const QByteArray &salt) {
|
||||
return QPasswordDigestor::deriveKeyPbkdf2(QCryptographicHash::Sha3_512, password, salt, PBKDF2_ITERATION_COUNT, PBKDF2_LENGTH);
|
||||
}
|
||||
|
||||
QByteArray Cryptographic::salt() {
|
||||
QByteArray number = QByteArray::number(QRandomGenerator::system()->generate64());
|
||||
QByteArray numberHash = QCryptographicHash::hash(number, QCryptographicHash::Sha512);
|
||||
return numberHash.toBase64();
|
||||
}
|
39
src/Cryptographic.h
Normal file
39
src/Cryptographic.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2020, WindTerm.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTOGRAPHIC_H
|
||||
#define CRYPTOGRAPHIC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class QByteArray;
|
||||
|
||||
class Cryptographic {
|
||||
public:
|
||||
Cryptographic() = default;
|
||||
|
||||
static QByteArray decrypt(const QByteArray &data, const QByteArray &pbkdf2);
|
||||
static QByteArray encrypt(const QByteArray &data, const QByteArray &pbkdf2);
|
||||
static QByteArray pbkdf2(const QByteArray &password, const QByteArray &salt);
|
||||
static QByteArray salt();
|
||||
|
||||
private:
|
||||
static QByteArray doCrypt(QByteArray data, const QByteArray &key, const QByteArray &iv, int enc);
|
||||
static QByteArray iv(const QByteArray &pbkdf2);
|
||||
static QByteArray key(const QByteArray &pbkdf2);
|
||||
};
|
||||
|
||||
#endif // CRYPTOGRAPHIC_H
|
@ -8,6 +8,10 @@ Below is a list of (some) WindTerm components in alphabetical order, along with
|
||||
|
||||
A quick circular buffer template class.
|
||||
|
||||
## Cryptographic.h/cpp
|
||||
|
||||
A very safe encryption class using the PBKDF2-algorithm as defined in RFC 8018. WindTerm uses this class together with the user's master password to protect user data, including passwords, private keys and so on.
|
||||
|
||||
## Onigmo
|
||||
|
||||
An improved version based on Onigmo 5.13.5. In particular, **the addition of iterator makes it possible to match gap buffer or nonadjacent memory blocks.** Please refer to the sample files for how to use.
|
||||
|
Loading…
Reference in New Issue
Block a user