From d28e31a4a981c4038c48041b7db1f6cbe1f2f111 Mon Sep 17 00:00:00 2001 From: Stefan Suhren Date: Tue, 22 Sep 2015 19:02:19 +0200 Subject: Repariere RSA Header einlesen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Springe über den Header, wenn die AES Daten gefunden wurden. Nutze die DER Funktion, die mit dem OpenSSL RSA Werkzeug kompatible ist. Nutze Macros für das Fehlerabfangen in RSA decrypt. --- crypt/hybridcrypt.cpp | 44 +++++++++++++++++++++++++++----------------- crypt/hybridcrypt.h | 3 ++- 2 files changed, 29 insertions(+), 18 deletions(-) (limited to 'crypt') diff --git a/crypt/hybridcrypt.cpp b/crypt/hybridcrypt.cpp index c5646d0..c1eddcf 100644 --- a/crypt/hybridcrypt.cpp +++ b/crypt/hybridcrypt.cpp @@ -29,7 +29,7 @@ HybridCrypt::~HybridCrypt() EVP_cleanup(); // Falls das nächste Ausgelassen wird, könnte ein Speicherleck auftreten, - // wenn die BIO Api verwendet wurde (Base64 transformationen) + // wenn die BIO Api verwendet wurde (Base64 Transformationen) CRYPTO_cleanup_all_ex_data(); // Lösche den CSPRNG sicher @@ -190,23 +190,33 @@ void HybridCrypt::decrypt(QString infileName, QString outfileName) QByteArray aesIv(EVP_CIPHER_iv_length(EVP_aes_256_cbc()), 0); // Versuche alle Header zu entschlüsseln - for (qint32 i = 0; i < keyCount && tmpData.length() == 0; i++) + for (qint32 i = 0; i < keyCount; i++) { infileStream >> tmpDataLength; - tmpData.resize(tmpDataLength); - infileStream.readRawData(tmpData.data(), tmpData.length()); - // Versuche nur den RSA Block zu entschlüsseln, - // wenn die Modulogröße des Nutzerschlüssels auf die - // des zum Verschlüsseln genutzten Schlüssels passt. - if (tmpDataLength == RSA_size(userKeypair->pkey.rsa)) + // Finde den Anfang der AES verschlüsselten Daten, + // wenn der AES Key und IV gefunden wurden + if (tmpData.length() != 0) { - tmpData = decryptAesData(userKeypair, tmpData); + infileStream.skipRawData(tmpDataLength); } else { - // Um in die nächste Entschlüsselungsrunde zu kommen - tmpData.resize(0); + tmpData.resize(tmpDataLength); + infileStream.readRawData(tmpData.data(), tmpData.length()); + + // Versuche nur den RSA Block zu entschlüsseln, + // wenn die Modulogröße des Nutzerschlüssels auf die + // des zum Verschlüsseln genutzten Schlüssels passt. + if (tmpDataLength == RSA_size(userKeypair->pkey.rsa)) + { + tmpData = decryptAesData(userKeypair, tmpData); + } + else + { + // Um in die nächste Entschlüsselungsrunde zu kommen + tmpData.resize(0); + } } } @@ -342,8 +352,7 @@ void HybridCrypt::importUserKeypair(QString keyfileName, QString password) } else if (keyfileExtension == "der") { - userKeypair = d2i_PKCS8PrivateKey_fp(keyfile, NULL, NULL, - (void *) password.toStdString().c_str()); + userKeypair = d2i_PrivateKey_fp(keyfile, NULL); } else { @@ -560,9 +569,9 @@ QByteArray HybridCrypt::decryptAesData(EVP_PKEY *pkey, QByteArray data) (unsigned char *) data.data(), data.length()) <= 0) { // Wenn der Fehler von OAEP kommt, ignoriere fürs erste - if (ERR_GET_LIB(ERR_peek_error()) == 4 && - ERR_GET_FUNC(ERR_peek_error()) == 161 && - ERR_GET_REASON(ERR_peek_error()) == 121) + if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_RSA && + ERR_GET_FUNC(ERR_peek_error()) == RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1 && + ERR_GET_REASON(ERR_peek_error()) == RSA_R_OAEP_DECODING_ERROR) { // Lösche Error aus der Schlange ERR_get_error(); @@ -582,7 +591,8 @@ QByteArray HybridCrypt::decryptAesData(EVP_PKEY *pkey, QByteArray data) return out; } -void HybridCrypt::writeRsaHeader(QDataStream *outfileStream, EVP_PKEY *pkey, QByteArray aesData) +void HybridCrypt::writeRsaHeader(QDataStream *outfileStream, EVP_PKEY *pkey, + QByteArray aesData) { QByteArray data = encryptAesData(pkey, aesData); diff --git a/crypt/hybridcrypt.h b/crypt/hybridcrypt.h index 5ed558a..343ce9b 100644 --- a/crypt/hybridcrypt.h +++ b/crypt/hybridcrypt.h @@ -120,7 +120,8 @@ private: * @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); + void writeRsaHeader(QDataStream *outfileStream, EVP_PKEY *pkey, + QByteArray aesData); /** * @brief Ließt einen Empfängerschlüssel aus einer Datei ein. -- cgit v1.2.3-70-g09d2