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(); }
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()); }
/** * @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; }
// 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); }
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 {
// 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); }
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; }