Skip to content

Instantly share code, notes, and snippets.

@Moligaloo
Last active March 19, 2024 12:37
Show Gist options
  • Save Moligaloo/5944425 to your computer and use it in GitHub Desktop.
Save Moligaloo/5944425 to your computer and use it in GitHub Desktop.
Using libtomcrypt to encrypt and decrypt file
#include <tomcrypt.h>
#include <QFile>
#include <QDir>
// interface
class Crypto{
public:
static int getKeySize();
static void setKey(const char *key);
static const char *encrypt(const char *in, size_t &length);
static const char *decrypt(const char *in, size_t &length);
static void encryptFile(const QString &from, const QString &to);
static void decryptFile(const QString &from, const QString &to);
static int encryptFiles(const QString &dirname, const QString &fromSuffix, const QString &toSuffix);
static int decryptFiles(const QString &dirname, const QString &fromSuffix, const QString &toSuffix);
static QString getVersion();
};
// implementation
static const int KEYSIZE = 8;
static const int BLOCKSIZE = 8;
static const int ROUNDS = 16;
static unsigned char key[KEYSIZE];
int Crypto::getKeySize(){
return KEYSIZE;
}
void Crypto::setKey(const char *k){
memcpy(key, k, KEYSIZE);
}
QString Crypto::getVersion(){
return SCRYPT;
}
typedef int (* process_func)(const unsigned char *, unsigned char *, symmetric_key *skey);
static const char *process(const char *in, size_t &length, process_func func){
length += length % BLOCKSIZE;
char *out = new char[length];
symmetric_key skey;
des_setup(key, KEYSIZE, ROUNDS, &skey);
const int n = length / BLOCKSIZE;
for(int i=0; i<n; i++){
const int offset = i * BLOCKSIZE;
const unsigned char *ct = reinterpret_cast<const unsigned char *>(in + offset);
unsigned char *pt = reinterpret_cast<unsigned char *>(out + offset);
func(ct, pt, &skey);
}
des_done(&skey);
return out;
}
const char *Crypto::encrypt(const char *in, size_t &length){
return process(in, length, des_ecb_encrypt);
}
const char *Crypto::decrypt(const char *in, size_t &length){
return process(in, length, des_ecb_decrypt);
}
void Crypto::encryptFile(const QString &from, const QString &to){
QFile in(from);
if(!in.open(QIODevice::ReadOnly))
return;
QFile out(to);
if(!out.open(QIODevice::WriteOnly))
return;
QByteArray data = in.readAll();
size_t length = data.length();
qint32 originalLength = length;
const char *result = Crypto::encrypt(data.constData(), length);
out.write((char *)&originalLength, sizeof(qint32));
out.write(result, length);
delete[] result;
}
void Crypto::decryptFile(const QString &from, const QString &to){
QFile in(from);
if(!in.open(QIODevice::ReadOnly))
return;
QFile out(to);
if(!out.open(QIODevice::WriteOnly))
return;
qint32 originalLength = 0;
in.read((char *)&originalLength, sizeof(qint32));
QByteArray data = in.readAll();
size_t length = data.length();
const char *result = Crypto::decrypt(data.constData(), length);
out.write(result, originalLength);
delete[] result;
}
typedef void (* process_method)(const QString &, const QString &);
static int process_files(const QString &dirname, const QString &fromSuffix, const QString &toSuffix, process_method method){
QDir dir(dirname);
int count = 0;
foreach(QFileInfo info, dir.entryInfoList(QStringList() << "*." + fromSuffix)){
QString from = info.absoluteFilePath();
QString to = dir.filePath(QString("%1.%2").arg(info.baseName()).arg(toSuffix));
method(from, to);
count ++;
}
return count;
}
int Crypto::encryptFiles(const QString &dirname, const QString &fromSuffix, const QString &toSuffix){
return process_files(dirname, fromSuffix, toSuffix, &Crypto::encryptFile);
}
int Crypto::decryptFiles(const QString &dirname, const QString &fromSuffix, const QString &toSuffix){
return process_files(dirname, fromSuffix, toSuffix, &Crypto::decryptFile);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment