#ifndef HYBRIDCRYPT_H #define HYBRIDCRYPT_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cryptexception.h" /** * @brief Eine Klasse die sich um hybride Verschlüsselung mittels RSA und AES kümmert. */ class HybridCrypt { public: /** * @brief Initialisiert OpenSSL. */ HybridCrypt(); /** * @brief Räumt OpenSSL auf. */ ~HybridCrypt(); /** * @brief Ließt eine Datei ein und schreibt diese verschlüsselt. * mit den übergebenen Schlüsseln und dem Nutzerschlüssel. * @param infileName Der Name der zu verschlüsselnde Datei. * @param outfileName Der Name der verschlüsselten Datei (wird angelegt/überschrieben). * @param recipientKeyfileNames Die Schlüssel der Empfänger, * mit denen die Datei verschlüsselt wird (Sollte nicht den Nutzerschlüssel enthalten). * @throws CryptException Fehler, die bei der Verschlüsselung auftreten können. */ void encrypt(QString infileName, QString outfileName, QVector recipientKeyfileNames); /** * @brief Entschlüsselt die übergeben Datei mit dem Nutzerschlüssel und schreibt diese entschlüsselt. * @param infileName Der Name der zu entschlüsselnden Datei. * @param outfileName Der Name der entschlüsselten Datei (wird angelegt/überschrieben). * @throws CryptException Fehler, die bei der Verschlüsselung auftreten können. */ void decrypt(QString infileName, QString outfileName); /** * @brief Erzeugt sicher ein neues RSA Schlüsselpaar zur Verwendung in #encrypt und #decrypt. * Sollte mittel #exportUserKeypair exportiert werden. * @throws CryptException Fehler, die bei der Verschlüsselung auftreten können. */ void createKeypair(); /** * @brief Importiert das Schlüsselpaar des Nutzers zur Verwendung in #encrypt und #decrypt. * @param keyfileName Der Name der Schlüsseldatei im (PEM|DER|NET|ASC) Format, die importiert werden soll. * @param password Das Password mit dem der private Schlüssel in der Datei verschlüsselt ist. * @throws CryptException Fehler, die bei der Verschlüsselung auftreten können. */ void importUserKeypair(QString keyfileName, QString password); /** * @brief Exportiert das Schlüsselpaar des Nutzers im PEM-Format. * @param keyfileName Der Name der Datei in die das Schlüsselpaar exportiert wird (wird angelegt/überschrieben). * @param password Das Password mit dem der private Schlüssel des Nutzers verschlüsselt wird. * @throws CryptException Fehler, die bei der Verschlüsselung auftreten können. */ void exportUserKeypair(QString keyfileName, QString password); /** * @brief Exportiert den öffentlichen Schlüssel des Nutzers im (PEM|DER|NET|ASC) Format. * @param keyfileName Der Name der Datei in den der öffentliche Schlüssel exportiert wird (wird angelegt/überschrieben). * @throws CryptException Fehler, die bei der Verschlüsselung auftreten können. */ void exportPublicUserKey(QString keyfileName); /** * @brief Gibt an, ob eine Nutzerschlüssel bereits importiert/erzeugt wurde. * @return Wahr, falls ein Nutzerschlüssel existiert, ansonsten falsch. */ bool isUserKeyInitialised(); private: EVP_PKEY *userKeypair; ///< Enthält nur den privaten Schlüssel, da OpenSSL nicht mehr braucht. /** * @brief Verschlüsselt den IV und den Key vom AES mit RSA. * Und nutzt als Padding RSA_OAEP_PADDING. * @param pkey Der EVP_PKEY mit dem verschlüsselt wird. * @param data Der AES Key und IV. * @return Den RSA Verschlüsselten Block. */ QByteArray encryptAesData(EVP_PKEY *pkey, QByteArray data); /** * @brief Verschlüsselt den IV und den Key vom AES mit RSA. * Und nutzt als Padding RSA_OAEP_PADDING. * @param pkey Der EVP_PKEY mit dem verschlüsselt wurde. * @param data Der RSA Verschlüsselte Block. * @return Der Aes Key and IV. (Länge is null, falls OAEP Fehler auftrat. */ QByteArray decryptAesData(EVP_PKEY *pkey, QByteArray data); /** * @brief Schreibt den verschlüsselten RSA Header in den outfileStream. * @param outfileStream Der Stream in den der verschlüsselte Header geschrieben wird. * @param pkey Der EVP_PKEY mit dem verschlüsselt wurde. * @param aesData Der AES Key and IV. */ void writeRsaHeader(QDataStream *outfileStream, EVP_PKEY *pkey, QByteArray aesData); /** * @brief Ließt einen Empfängerschlüssel aus einer Datei ein. * @param keyfileName Der Dateiname aus dem der öffentliche Schlüssel gelsen wird. * @return Der EVP_PKEY für OpenSSL. */ EVP_PKEY *readRecipientKey(QString keyfileName); /** * @brief Gibt an, ob der Zufallszahlengenerator von OpenSSL mit ausreichend Entropie initialisiert wurde. * @return Gibt wahr zurück wenn ausreichend intialisert wurde, ansonsten falsch. */ bool isCsprngSeeded(); /** * @brief Holt Zufallsblöcke aus dem Csprng. * @param count Die Anzahl der Zufallsbytes die geholt werden sollen. * @return Ein QByteArray mit den Zufallsblöcken. */ QByteArray getCsprngBytes(int count); /** * @brief Überprüft, ob der Schlüssel vom Typ RSA ist. * @param key Der Schlüssel, der überprüft wird. * @return Gibt wahr zurück, falls Key vom Typ RSA ist, ansonsten flasch. */ bool isKeyRsa(EVP_PKEY *key); /** * @brief Wirft eine CryptException mit dem OpenSSL Fehler. */ void throwOpenSslException(); /** * @brief Wirft eine CryptException, falls der Schlüssel nicht RSA ist. * @param key Der Pointer, der auf NULL gesetzt wird, nachdem der Schlüssel abgräumt wurde. */ void throwExceptionIfEvpKeyIsNotRsa(EVP_PKEY **key); /** * @brief Wirft eine Exception, falls der Zufallszahlengenerator nicht initialisiert wurde. */ void throwExceptionIfCsprngIsNotSeeded(); /** * @brief throwExceptionIfUserKeyIsNull * Wift eine Exception, falls kein Nutzerschlüssel vorhanden ist. */ void throwExceptionIfUserKeyIsNull(); /** * @brief Räumt den Schlüssel hinter key ab. * @param key Der Pointer, der auf NULL gesetzt wird. */ void freeEvpKey(EVP_PKEY **key); /** * @brief Räumt den Kontext hinter ctx ab. * @param ctx Der Pointer, der auf NULL gesetzt wird. */ void freeCipherCtx(EVP_CIPHER_CTX **ctx); /** * @brief Räumt den Kontext hinter ctx ab. * @param ctx Der Pointer, der auf NULL gesetzt wird. */ void freePkeyCtx(EVP_PKEY_CTX **ctx); }; #endif // HYBRIDCRYPT_H