Created
June 21, 2017 07:46
-
-
Save NorbertFenk/b98e3a0f51f4b737817eae3657ee16b0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <QString> | |
#include <QByteArray> | |
#include <QDebug> | |
#include <QFile> | |
#include <QCryptographicHash> | |
#include <botan/pkcs8.h> | |
#include <botan/hex.h> | |
#include <botan/pk_keys.h> | |
#include <botan/pubkey.h> | |
#include <botan/auto_rng.h> | |
#include <botan/rng.h> | |
#include <botan/rsa.h> | |
#include <botan/data_src.h> | |
#include <botan/x509self.h> | |
QString readInput (const QString &filePath) | |
{ | |
QFile input(filePath); | |
QString rawText; | |
if (!input.open(QIODevice::ReadOnly)) { | |
qDebug() << "File reading error" << endl; | |
} | |
rawText = input.readAll(); | |
input.close(); | |
return rawText; | |
} | |
std::vector<uint8_t> convertQStringToStdVector(const QString &string) | |
{ | |
std::string stdString = string.toStdString(); | |
std::vector<uint8_t> rawTextVector(stdString.data(), stdString.data()+stdString.length()); | |
// std::cout << "vec: " << plaintextVector.size() << std::endl; | |
// for (auto it : rawTextVector) { | |
// std::cout << it << std::endl; | |
// } | |
return rawTextVector; | |
} | |
std::vector<uint8_t> convertQByteArrayToStdVector(const QByteArray &array) | |
{ | |
std::string stdString = array.toStdString(); | |
std::vector<uint8_t> rawStdVector(stdString.data(), stdString.data()+stdString.length()); | |
// std::cout << "vec: " << plaintextVector.size() << std::endl; | |
// for (auto it : rawTextVector) { | |
// std::cout << it << std::endl; | |
// } | |
return rawStdVector; | |
} | |
Botan::Private_Key *generateKeys(Botan::RSA_PrivateKey RSAKey, Botan::AutoSeeded_RNG *rng) | |
{ | |
//Public-key cryptography standard 8 | |
QString privateKeyPEM = QString::fromStdString(Botan::PKCS8::PEM_encode(RSAKey)); | |
QString publicKeyPEM = QString::fromStdString(Botan::X509::PEM_encode(RSAKey)); | |
qDebug() << privateKeyPEM << endl; | |
qDebug() << publicKeyPEM << endl; | |
//store in memory | |
Botan::DataSource_Memory privateKeySource(privateKeyPEM.toStdString()); | |
//load keypair, Private_Key is child of Public_Key | |
Botan::Private_Key *keys(Botan::PKCS8::load_key(privateKeySource, *rng)); | |
return keys; | |
} | |
QString makeCert(Botan::Private_Key *keys, Botan::AutoSeeded_RNG *rng) | |
{ | |
Botan::X509_Cert_Options certOptions; | |
certOptions.email = "[email protected]"; | |
certOptions.common_name = "Opswat Inc."; | |
Botan::X509_Certificate cert = Botan::X509::create_self_signed_cert(certOptions, *keys, "SHA-256", *rng); | |
QString certString = QString::fromStdString(cert.PEM_encode()); | |
return certString; | |
} | |
QByteArray generateHash(const QString &data) | |
{ | |
QCryptographicHash hash(QCryptographicHash::Sha256); | |
hash.addData(data.toUtf8()); | |
return hash.result(); | |
} | |
std::vector<uint8_t> encryptData(Botan::Private_Key *keys, Botan::AutoSeeded_RNG *rng, const std::vector<uint8_t> &dataVector) | |
{ | |
//create encryptor with pk | |
Botan::PK_Encryptor_EME encryptor(*keys, *rng, "EME1(SHA-256)"); //With key being the key you want to encrypt messages to. The padding method to use is specified in eme. | |
qDebug() << "maximum_input_size: " << encryptor.maximum_input_size() << endl; | |
//encrypt hash | |
return encryptor.encrypt(dataVector, *rng); | |
} | |
std::vector<uint8_t> signData(Botan::Private_Key *keys, Botan::AutoSeeded_RNG *rng, const std::vector<uint8_t> &dataVector) | |
{ | |
Botan::PK_Signer signer(*keys, *rng, "EMSA4(SHA-256)"); //signature format | |
// signer.update(ciphertext); | |
// std::vector<uint8_t> signature = signer.signature(rng); | |
return signer.sign_message(dataVector, *rng); | |
} | |
bool verifyData(Botan::Private_Key *keys, const std::vector<uint8_t> &dataVector, const std::vector<uint8_t> &signature) | |
{ | |
Botan::PK_Verifier verifier(*keys, "EMSA4(SHA-256)"); | |
// verifier.update(ciphertext); | |
// std::cout << "is " << (verifier.check_signature(signature)? "valid" : "invalid"); | |
return verifier.verify_message(dataVector, signature); | |
} | |
QByteArray decryptData(Botan::Private_Key *keys, Botan::AutoSeeded_RNG *rng, const std::vector<uint8_t> &dataVector) | |
{ | |
Botan::PK_Decryptor_EME decryptor(*keys, *rng, "EME1(SHA-256)"); | |
return QByteArray::fromHex(Botan::hex_encode(decryptor.decrypt(dataVector)).data()); | |
} | |
int main (int argc, char* argv[]) | |
{ | |
if (argc != 2) { | |
qDebug() << "Please add a valid file path"; | |
qDebug() << argv[0] << " <file path>"; | |
return 1; | |
} | |
Q_UNUSED(argc); | |
QString rawInput = readInput(argv[1]); | |
qDebug() << rawInput << endl; | |
Botan::AutoSeeded_RNG rng; | |
Botan::RSA_PrivateKey RSAKey(rng, 2048); | |
Botan::RSA_PrivateKey RSAKey2(rng, 2048); | |
Botan::Private_Key *keys = generateKeys(RSAKey, &rng); | |
Botan::Private_Key *keys2 = generateKeys(RSAKey2, &rng); | |
qDebug() << makeCert(keys, &rng) << endl; | |
QByteArray hash = generateHash(rawInput); | |
qDebug() << "hashed data: " << hash.toHex() << endl; | |
std::vector<uint8_t> hashVector = convertQByteArrayToStdVector(hash); | |
std::vector<uint8_t> dataVector = convertQStringToStdVector(rawInput); | |
std::vector<uint8_t> ciphertext = encryptData(keys, &rng, hashVector); | |
std::vector<uint8_t> ciphertextOfStringInput = encryptData(keys, &rng, dataVector); | |
std::vector<uint8_t> signature = signData(keys, &rng, ciphertext); | |
std::vector<uint8_t> signatureOfStringInput = signData(keys, &rng, ciphertextOfStringInput); | |
qDebug() << "Signature: " << Botan::hex_encode(signature).c_str() << endl; | |
qDebug() << "Message is { " << (verifyData(keys, ciphertext, signature) ? "valid" : "invalid") << " }" << endl; | |
qDebug() << "Message is { " << (verifyData(keys2, ciphertext, signature) ? "valid" : "invalid") << " }" << endl; | |
qDebug() << "Message is { " << (verifyData(keys, ciphertextOfStringInput, signatureOfStringInput) ? "valid" : "invalid") << " }" << endl; | |
qDebug() << "decoded: " << decryptData(keys, &rng, ciphertext).toHex() << endl; | |
qDebug() << "hash: " << hash.toHex() << endl; | |
qDebug() << "decoded text: " << QString::fromUtf8(decryptData(keys, &rng, ciphertextOfStringInput)) << endl; | |
qDebug() << "original text: " << rawInput << endl; | |
delete keys; | |
delete keys2; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment