QByteArray EncryptioNgSimliteDecryptor::decrypt(const QByteArray &data, bool *ok)
{
	if (ok)
		*ok = false;

	if (!Valid)
		return data;

	//check if the message has at least the length of the shortest possible encrypted message
	if (data.length() < 192)
		return data;

	//decode the message from the Base64 encoding
	QCA::Base64 decoder(QCA::Decode);
	QCA::SecureArray decodedMessage = decoder.stringToArray(data);

	if (!decoder.ok())
		return data;

	//extract the Blowfish key (first 128 characters)
	QCA::SecureArray encryptedBlowfishKey(decodedMessage.toByteArray().left(128));
	//and the encrypted message (the rest)
	QCA::SecureArray encryptedMessage(decodedMessage.toByteArray().mid(128));

	QCA::SymmetricKey blowfishKey;
	if (!DecodingKey.decrypt(encryptedBlowfishKey, &blowfishKey, QCA::EME_PKCS1_OAEP))
		return data;

	//recreate the initialization vector (should be the same as the one used for ciphering)
	char ivec[8] = {0, 0, 0, 0, 0, 0, 0, 0};
	QCA::InitializationVector iv(QByteArray(ivec, 8));
	//now that we have the symmetric Blowfish key, we can decrypt the message;
	//create a 128 bit Blowfish cipher object using Cipher Block Chaining (CBC) mode,
	//with default padding and for decoding
	QCA::Cipher cipher(QString("blowfish"), QCA::Cipher::CBC, QCA::Cipher::DefaultPadding, QCA::Decode, blowfishKey, iv);

	//decipher the message (put the message into the decoding cipher object)
	QCA::SecureArray plainText = cipher.process(encryptedMessage);
	if (!cipher.ok())
		return data;

	//check whether the decrypted data length is at least the size of the header -
	//if not, then we have an invalid message
	if (plainText.size() < (int)sizeof(sim_message_header))
		return data;

	//extract the header from the decrypted data and check if the magic number is
	//correct
	sim_message_header head;
	memcpy(&head, plainText.data(), sizeof(sim_message_header));
	if (head.magicFirstPart != SIM_MAGIC_V1_1 || head.magicSecondPart != SIM_MAGIC_V1_2)
		return data;

	if (ok)
		*ok = true;

	//the message has been decrypted! :D
	//put it into the input/output byte array
	return cp2unicode(&plainText.data()[sizeof(sim_message_header)]).toUtf8();
}
예제 #2
0
QString Security::decrypt(QString input)
{
    if(input.isEmpty())
    {
        return input;
    }
    QCA::Initializer init = QCA::Initializer();
    QCA::SymmetricKey key = QCA::SymmetricKey(QCA::SecureArray(ENC_KEY));
    QCA::InitializationVector iv = QCA::InitializationVector(QCA::SecureArray(ENC_INIT_VECTOR));
    QCA::Cipher cipher = QCA::Cipher(QString("aes128"), QCA::Cipher::CBC,
                                     QCA::Cipher::DefaultPadding, QCA::Encode,
                                     key, iv);
    if (!QCA::isSupported("aes128-cbc-pkcs7"))
    {
        qDebug() << "AES128 CBC PKCS7 not supported - "
                    "please check if qca-ossl plugin is"
                    "installed correctly !";
        return "";
    }
    cipher.setup(QCA::Decode, key, iv);
    QCA::SecureArray encryptedData = QCA::SecureArray(QCA::hexToArray(input));
    QCA::SecureArray decryptedData = cipher.process(encryptedData);
    //check if decryption succeded
    if (!cipher.ok())
    {
        return "";
    }
    return QString(decryptedData.data());
}
예제 #3
0
/**
 * @paragraph This method decrypts a system encrypted hash
 * @brief ServerPanel::DecryptEntity
 * @param QByteArray qbaKey
 * @param QByteArray qbaVector
 * @param QByteArray qbaHash
 * @return QString
 */
QVariantMap ServerPanel::DecryptEntity(QByteArray qbaKey, QByteArray qbaVector, QByteArray qbaHash) {
    // Initialize the cryptographer
    QCA::Initializer qiInitializer = QCA::Initializer();
    // Create the cipher
    QCA::Cipher qcrCipher          = QCA::Cipher("aes128", QCA::Cipher::CBC, QCA::Cipher::DefaultPadding, QCA::Decode, QCA::SymmetricKey(qbaKey), QCA::InitializationVector(qbaVector));
    // Decode the hash
    QCA::SecureArray qsaPlain      = qcrCipher.process(QCA::SecureArray(qbaHash));
    // Setup the return map
    QVariantMap qvmReturn;
    // Check the decryption status
    if (qcrCipher.ok()) {
        // Set the plain text entity
        qvmReturn.insert("sPlainText", QString(qsaPlain.data()));
        // Set the decryption status
        qvmReturn.insert("bSuccess", true);
    } else {
        // Set the decryption status
        qvmReturn.insert("bSuccess", false);
    }
    // Return the map
    return qvmReturn;
}
예제 #4
0
// Click on "OK"
void AdminPasswordOffice::setNewPassword() {

	// Get the current office password (without the salt)
	ConfigData cfg(pwOffice);
	QCA::SecureArray officeNoSalt = cfg.getOfficePasswordWithoutSalt();
	QString address = cfg.getAddress();

	// Check if old password for authorisation is the right one
	if(oldPw->text().toLatin1() != officeNoSalt.data()) {
		QMessageBox::warning(this,"Wrong Password","The current office password you entered is incorrect. Please enter the right password.");
		oldPw->setFocus();
		return;
	}

	// Make sure the new password matches the confirmation
	if(newPw->text() != newPwConfirm->text()) {
		QMessageBox::warning(this,"Invalid Password","The new password does not match its confirmation. Please try again!");
		newPwConfirm->setFocus();
		return;
	}

	// Make sure the new password has at least 4 characters
	if(newPw->text().length() < 4) {
		QMessageBox::warning(this,"Password too short","The password you entered is too short. Please enter one with at least 4 characters.");
		newPwConfirm->setFocus();
		return;
	}


	// Display splashscreen while working
	busy->show();
	qApp->setOverrideCursor(Qt::BusyCursor);
	// We need to call this 5 times (with 10ms sleep in between), otherwise the "busy dialog" wouldn't get painted (i.e. only a grey rectangle would be shown)
	for(unsigned int i = 0; i < 5; ++i) {
		qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
		I::sleep(10);
	}


	// This string is used to make sure (on the server) the submitted data is valid
	QString salt = "bookercheck";
	QString pw = salt + oldPw->text() + "_._._._" + newPw->text();

	// Encrypt the salt + new password
	Cryptor cr(officeNoSalt, true);
	pw = cr.encrypt(pw.toLatin1()).join("__");


	// The current office password is encrypted with the iv
	cr.setPassword(cr.getIv());

	// We submit the new pw and also the old password (needed to update pws in database)
	QUrlQuery params;
	params.addQueryItem("newdata", pw);
	params.addQueryItem("officepw", cr.encrypt(officeNoSalt.data()).join("__"));

	// Request data file (encrypted with office password)
	// First we set all the headers:
	QNetworkRequest request(QUrl("http://" + address + "/booker/update/officepw.php"));
	request.setRawHeader("Host", address.toLatin1());
	request.setRawHeader("User-Agent", "Mozilla/5.0 Firefox");
	request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
	request.setRawHeader("Accept-Language", "en-us;q=0.7,en;q=0.3");
	request.setRawHeader("Accept-Encoding", "gzip,deflate");
	request.setRawHeader("Accept-Charset", "windows-1252,utf-8;q=0.7,*;q=0.7");
	request.setRawHeader("Keep-Alive", "300");
	request.setRawHeader("Connection", "keep-alive");
	request.setRawHeader("Referer", "booker.qt");
	request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");

	// Send request with salt + new password as POST data
	manager.post(request,params.toString().toLatin1());

	// Disable lineedits and buttons
	oldPw->setEnabled(false);
	newPw->setEnabled(false);
	newPwConfirm->setEnabled(false);
	ok->setEnabled(false);
	cancel->setEnabled(false);

}
예제 #5
0
	if (s != SECSuccess) {
	    qDebug() << "DigestBegin failed";
	    return;
	}
    }

    void update(const QCA::MemoryRegion &a)
    {
	PK11_DigestOp(m_context, (const unsigned char*)a.data(), a.size());
    }

    QCA::MemoryRegion final()
    {
	unsigned int len = 0;
	QCA::SecureArray a( 64 );
	PK11_DigestFinal(m_context, (unsigned char*)a.data(), &len, a.size());
	a.resize(len);
	return a;
    }

private:
    PK11SlotInfo *m_slot;
    int m_status;
    PK11Context *m_context;
    SECOidTag m_hashAlgo;
};


//-----------------------------------------------------------
class nssHmacContext : public QCA::MACContext
{
예제 #6
0
// Click on "OK"
void AdminPasswordMaster::setNewPassword() {

	// Get the current office password (without the salt)
	ConfigData cfg(pwOffice);
	QCA::SecureArray officeNoSalt = cfg.getOfficePasswordWithoutSalt();
	QCA::SecureArray oldMaster = cfg.getMasterPassword();

	// Check if old password for authorisation is the right one
	if(oldPw->text().toLatin1() != oldMaster.data()) {
		QMessageBox::warning(this,"Wrong Password","The current Master password you entered is incorrect. Please enter the right password.");
		oldPw->setFocus();
		return;
	}

	// Make sure the new password matches the confirmation
	if(newPw->text() != newPwConfirm->text()) {
		QMessageBox::warning(this,"Invalid Password","The new password does not match its confirmation. Please try again!");
		newPwConfirm->setFocus();
		return;
	}

	// Make sure the new password has at least 4 characters
	if(newPw->text().length() < 4) {
		QMessageBox::warning(this,"Password too short","The password you entered is too short. Please enter one with at least 4 characters.");
		newPwConfirm->setFocus();
		return;
	}


	// Show busy cursor
	qApp->setOverrideCursor(Qt::BusyCursor);

	// Disable lineedits and buttons
	oldPw->setEnabled(false);
	newPw->setEnabled(false);
	newPwConfirm->setEnabled(false);
	ok->setEnabled(false);
	cancel->setEnabled(false);


	QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL",QString("masterpw%1").arg(QDateTime::currentMSecsSinceEpoch()));
	SaverDbCred s = cfg.getDbLogin();
	db.setHostName(s.host.data());
	db.setDatabaseName(s.database.data());
	db.setUserName(s.username.data());
	db.setPassword(s.password.data());

	bool error = false;

	if(!db.open()) {
		QMessageBox::critical(this,"ERROR","ERROR, unable to open database. Can't proceed!");
		error = true;
	} else {

		QSqlQuery query(db);
		query.prepare("SELECT txt FROM current WHERE id='master'");
		if(!query.exec()) {
			QMessageBox::critical(this,"ERROR","Error, unable to get old password (encrypted) from database. Unable to proceed");
			error = true;
		} else {
			if(query.size() != 1) {
				QMessageBox::critical(this,"ERROR","ERROR, received more than one result... don't know what to do...");
				error = true;
			} else {
				while(query.next()) {
					Cryptor cr(officeNoSalt, true);
					QByteArray pw = cr.decrypt(query.value(query.record().indexOf("txt")).toByteArray()).data();
					if(pw == "") {
						QMessageBox::critical(this,"ERROR", "ERROR, unable to decrypt old password! Can't continue...");
						error = true;
						continue;
					}
					QString pw_new = cr.encrypt(newPw->text().toLatin1()).join("\n");
					QSqlQuery query2(db);
					query2.prepare("UPDATE current SET txt=:pw WHERE id='master'");
					query2.bindValue(":pw",pw_new);
					if(!query2.exec()) {
						QMessageBox::critical(this,"ERROR", "ERROR, unable to save encrypted new password! Operation failed!!");
						error = true;
						continue;
					}
					query.clear();
				}
			}
		}
		query.clear();
	}
	db.close();

	// Restore cursor
	qApp->restoreOverrideCursor();

	// Success :-)
	if(!error) {

		QMessageBox::information(this,"Success!","The new master password was set successfully!");

		emit configChanged();

		this->accept();

		QMessageBox::information(this,"Pleae restart Booker","Please quit and restart Booker at your earliest convenience!");

	}

	// Re-enable lineedits and buttons
	oldPw->setEnabled(true);
	newPw->setEnabled(true);
	newPwConfirm->setEnabled(true);
	ok->setEnabled(true);
	cancel->setEnabled(true);

}
예제 #7
0
int main(int argc, char** argv)
{
    // the Initializer object sets things up, and
    // also does cleanup when it goes out of scope
    QCA::Initializer init;

    QCoreApplication app(argc, argv);

    // We need to ensure that we have certificate handling support
    if ( !QCA::isSupported( "cert" ) ) {
	std::cout << "Sorry, no PKI certificate support" << std::endl;
    	return 1;
    }

    // Read in a private key
    QCA::PrivateKey privKey;
    QCA::ConvertResult convRes;
    QCA::SecureArray passPhrase = "start";
    privKey = QCA::PrivateKey::fromPEMFile( "Userkey.pem", passPhrase, &convRes );
    if ( convRes != QCA::ConvertGood ) {
	std::cout << "Sorry, could not import Private Key" << std::endl;
	return 1;
    }

    // Read in a matching public key cert
    // you could also build this using the fromPEMFile() method
    QCA::Certificate pubCert( "User.pem" );
    if ( pubCert.isNull() ) {
	std::cout << "Sorry, could not import public key certificate" << std::endl;
	return 1;
    }
    // We are building the certificate into a SecureMessageKey object, via a
    // CertificateChain
    QCA::SecureMessageKey secMsgKey;
    QCA::CertificateChain chain;
    chain += pubCert;
    secMsgKey.setX509CertificateChain( chain );

    // build up a SecureMessage object, based on our public key certificate
    QCA::CMS cms;
    QCA::SecureMessage msg(&cms);
    msg.setRecipient(secMsgKey);

    // Some plain text - we use the first command line argument if provided
    QByteArray plainText = (argc >= 2) ? argv[1] : "What do ya want for nuthin'";

    // Now use the SecureMessage object to encrypt the plain text.
    msg.startEncrypt();
    msg.update(plainText);
    msg.end();
    // I think it is reasonable to wait for 1 second for this
    msg.waitForFinished(1000);

    // check to see if it worked
    if(!msg.success())
    {
	std::cout << "Error encrypting: " << msg.errorCode() << std::endl;
	return 1;
    }

    // get the result
    QCA::SecureArray cipherText = msg.read();
    QCA::Base64 enc;
    std::cout << plainText.data() << " encrypts to (in base 64): ";
    std::cout << qPrintable( enc.arrayToString( cipherText ) ) << std::endl;

    // Show we can decrypt it with the private key
    if ( !privKey.canDecrypt() ) {
	std::cout << "Private key cannot be used to decrypt" << std::endl;
	return 1;
    }
    QCA::SecureArray plainTextResult;
    if ( 0 == privKey.decrypt(cipherText, &plainTextResult, QCA::EME_PKCS1_OAEP ) ) {
	std::cout << "Decryption process failed" << std::endl;
	return 1;
    }

    std::cout << qPrintable( enc.arrayToString( cipherText ) );
    std::cout << " (in base 64) decrypts to: ";
    std::cout << plainTextResult.data() << std::endl;

    return 0;
}