WP::err QCACryptoInterface::generateKeyPair(QString &certificate, QString &publicKey, QString &privateKey, const SecureArray &keyPassword) { if(!QCA::isSupported("pkey") || !QCA::PKey::supportedIOTypes().contains(QCA::PKey::RSA)) { qDebug() << "RSA not supported!\n"; return WP::kError; } QCA::PrivateKey secretKey = QCA::KeyGenerator().createRSA(2048); if(secretKey.isNull()) { qDebug() << "Failed to make private RSA key\n"; return WP::kError; } privateKey = secretKey.toPEM(keyPassword); // public QCA::CertificateOptions opts; QCA::Certificate cert(opts, secretKey); certificate = cert.toPEM(); QCA::PublicKey pubkey = secretKey.toPublicKey(); publicKey = pubkey.toPEM(); return WP::kOk; }
void QCACryptoInterface::generateDHParam(QString &prime, QString &base, QString &secret, QString &pub) { QCA::KeyGenerator generator; QCA::DLGroup group = generator.createDLGroup(QCA::DSA_512); prime = group.p().toString(); base = group.g().toString(); QCA::PrivateKey privateKey = generator.createDH(group); secret = privateKey.toDH().x().toString(); pub = privateKey.toDH().y().toString(); }
QCA::PrivateKey EncryptioNgSimliteDecryptor::getPrivateKey(const Key &key) { QByteArray keyData = key.key().toByteArray().trimmed(); if (!keyData.startsWith(BEGIN_RSA_PRIVATE_KEY) || !keyData.endsWith(END_RSA_PRIVATE_KEY)) { Valid = false; return QCA::PrivateKey(); } keyData = keyData.mid(BEGIN_RSA_PRIVATE_KEY_LENGTH, keyData.length() - BEGIN_RSA_PRIVATE_KEY_LENGTH - END_RSA_PRIVATE_KEY_LENGTH).replace('\r', "").trimmed(); QCA::SecureArray certificate; QCA::Base64 decoder; decoder.setLineBreaksEnabled(true); certificate = decoder.decode(keyData); // just some fake security added keyData.fill(' ', keyData.size()); keyData.clear(); if (!decoder.ok()) { Valid = false; return QCA::PrivateKey(); } PKCS1Certificate::ConversionStatus status; PKCS1Certificate pkcs1; QCA::PrivateKey privateKey = pkcs1.privateKeyFromDER(certificate, status); if (PKCS1Certificate::OK != status) { Valid = false; return QCA::PrivateKey(); } if (!privateKey.canDecrypt()) { Valid = false; return QCA::PrivateKey(); } Valid = true; return privateKey; }
WP::err QCACryptoInterface::sign(const QByteArray &input, QByteArray &signature, const QString &privateKeyString, const SecureArray &keyPassword) { QCA::PrivateKey privateKey; QCA::ConvertResult convRes; privateKey = QCA::PrivateKey::fromPEM(privateKeyString, keyPassword, &convRes); if (convRes != QCA::ConvertGood) { std::cout << "Sorry, could not import Private Key" << std::endl; return WP::kError; } if(!privateKey.canSign()) { std::cout << "Error: this kind of key cannot sign" << std::endl; return WP::kError; } privateKey.startSign(QCA::EMSA3_MD5); privateKey.update(input); signature = privateKey.signature(); return WP::kOk; }
void QCACryptoInterface::generateKeyPair(const char* certificateFile, const char *publicKeyFile, const char *privateKeyFile, const char *keyPassword) { if(!QCA::isSupported("pkey") || !QCA::PKey::supportedIOTypes().contains(QCA::PKey::RSA)) { qDebug() << "RSA not supported!\n"; return; } QCA::PrivateKey secretKey = QCA::KeyGenerator().createRSA(2048); if(secretKey.isNull()) { qDebug() << "Failed to make private RSA key\n"; return; } secretKey.toPEMFile(privateKeyFile, keyPassword); // public QCA::CertificateOptions opts; QCA::Certificate cert(opts, secretKey); cert.toPEMFile(certificateFile); QCA::PublicKey pubkey = secretKey.toPublicKey(); pubkey.toPEMFile(publicKeyFile); }
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; }