Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Encrypt/decrypt data with QCA



  • Hello everyone,

    I've finally managed to setup QCA so that it seems to work and am now trying to get a hang of this.
    In the end, the goal is to write an encrypted file.
    For now, I am just trying to get the general encryption/decryption of data going.

    Here is my test method:

    void QcaTest::publicKeyEncryption()
    {
    	QCA::Initializer init;
    	
    	if (!QCA::isSupported("cert"))
    		QFAIL("Certificates are not supported.");
    	
    	QString privateKeyFile = QFINDTESTDATA("key.pem");
    	QCA::ConvertResult convertResult;
    	QCA::PrivateKey privateKey = QCA::PrivateKey::fromPEMFile(privateKeyFile, "test", &convertResult);
    	if (convertResult != QCA::ConvertGood)
    		QFAIL("Could not open private key.");
    	
    	QString publicCertificateFile = QFINDTESTDATA("cert.pem");
    	QCA::Certificate publicCertificate(publicCertificateFile);
    	if (publicCertificate.isNull())
    		QFAIL("Could not open public certificate.");
    	
    	QCA::CertificateChain publicCertificateChain;
    	publicCertificateChain += publicCertificate;
    	
    	QCA::SecureMessageKey messageKey;
    	messageKey.setX509CertificateChain(publicCertificateChain);
    	
    	QCA::CMS messageSyntax;
    	QCA::SecureMessage message(&messageSyntax);
    	message.setRecipient(messageKey);
    	
    	QByteArray plainText = "no more secrets";
    	
    	message.startEncrypt();
    	message.update(plainText);
    	message.end();
    	message.waitForFinished();
    	
    	if (!message.success())
    		QFAIL("Encryption failed.");
    	
    	QCA::SecureArray cipherText = message.read();
    	QCA::Base64 base64Encoding;
    	qDebug() << plainText.data() << "encrypts to (in base 64):";
    	qDebug() << base64Encoding.arrayToString(cipherText);
    	
    	QCA::SecureArray plainTextResult;
    	if (!privateKey.decrypt(cipherText, &plainTextResult, QCA::EME_PKCS1_OAEP))
    		QFAIL("Error decrypting.");
    	
    	qDebug() << "Decrypted text:" << plainTextResult.data();
    }
    

    This test fails with the following output:

    ********* Start testing of Tests::QcaTest *********
    Config: Using QtTest library 5.6.3, Qt 5.6.3 (i386-little_endian-ilp32 shared (dynamic) debug build; by MSVC 2015)
    PASS   : Tests::QcaTest::initTestCase()
    QDEBUG : Tests::QcaTest::publicKeyEncryption() no more secrets encrypts to (in base 64):
    QDEBUG : Tests::QcaTest::publicKeyEncryption() "MIIDEwYJKoZIhvcNAQcDoIIDBDCCAwACAQAxggLEMIICwAIBADCBpzCBmTELMAkGA1UEBhMCREUxDjAMBgNVBAgMBUJhV8KBMRIwEAYDVQQHDAlLYXJsc3J1aGUxEjAQBgNVBAoMCUdhbWVmb3JnZTEMMAoGA1UECwwDVE5UMRcwFQYDVQQDDA5UaG9tYXMgQml0dG5lcjErMCkGCSqGSIb3DQEJARYcdGhvbWFzLmJpdHRuZXJAZ2FtZWZvcmdlLmNvbQIJAPNRCyBGY3P2MA0GCSqGSIb3DQEBAQUABIICAHtjIURTgbyT041mwej7CPKa2FSb8Qy17wmhxUCScU8Pz6xK0eGF6qmBAhuIVPsZbkzMwZbB1oY1ZZawmVQBlSPYXwPixoewwwZk3ubOC4EWIZsO416ci4vEjbMtTypvDa8dIgZ4VHeBPjY7Gqb0gvhcPW+HPi+MZEEZh6c5dmv4JrP0f7cuOlkMCrolgp4FND2DI8FgyK/k8isFpJCjdoPkZODCOQ9fV5mijR6MrA7Y0NRpQxbhOIAzqQG4ZkQp46wqwYrHqqBT4hqPNH5UkT601YouiqfqxQpQr1eExNu8Nh49J0N32Rd3Tqj9o6x0gbcw0YTWK79x8/844rcLoXXMpqOV7HKh5ytnlyZiGGdZduP+qNJlnvq7eZaKGzHECb7KbHUjtKBXi471seUCUYjzPuf4RPrIyVxTorM6UK89M1y3pYa+CbHiQdv3iFVwRFwbaOLVoVcpLRX6dl9N/JQohJ18f6ON/4wGXZBNpYv0wSjVVX1X5ayc3cyH5Fin9Y00YX9ErcmNwyI9+zeHl4OKPM40aEr0l0pzj4KZXFFI0UifUqZIg1DV5eZPQRmgqm+pLeRzayDk2ZluVZmM/GgVutIVzUBcmfPHNJrheUdDyG5wFExWOJf5IBioAyf62Jk+lOwlG+TQ0JzwxAJnfDjgrbljvMuqnt/GTOPyic5yMDMGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQID62Og83xf+WAEHeeyB6BWBN2kPA8avH03XA="
    FAIL!  : Tests::QcaTest::publicKeyEncryption() Error decrypting.
    QcaTest.cpp(61) : failure location
    PASS   : Tests::QcaTest::cleanupTestCase()
    Totals: 2 passed, 1 failed, 0 skipped, 0 blacklisted
    ********* Finished testing of Tests::QcaTest *********
    

    I've created the corresponding certificate and key file myself with the following command:

    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
    

    Does someone see any obvious error with this code?
    I would also be grateful for some pointers on how to debug this. Currently, I see no way of knowing on why the PrivateKey::decrypt() method fails.


  • Lifetime Qt Champion

    Hi,

    Might be a silly question but did you check the examples from the module for a similar implementation ?


  • Qt Champions 2017

    Did you check with KeyGeneration encrypt and decrypt both from the QCA ? Most of the time issue could be something related algorithm used for generation of key.



  • @SGaist said in Encrypt/decrypt data with QCA:

    Might be a silly question but did you check the examples from the module for a similar implementation ?

    Yes, my code is basically the publickeyexample provided by QCA, just as a QTest.

    @dheerendra said in Encrypt/decrypt data with QCA:

    Did you check with KeyGeneration encrypt and decrypt both from the QCA ? Most of the time issue could be something related algorithm used for generation of key.

    I'm not sure if I understood correctly, but what I tried now was to generate a key directly in the code using the KeyGenerator class like this:

    void QcaTest::publicKeyEncryption()
    {
    	QCA::Initializer init;
    	
    	QCA::KeyGenerator generator;
    	QCA::PrivateKey privateKey = generator.createRSA(4096);
    	QCA::PublicKey publicKey = privateKey.toPublicKey();
    	
    	QCA::SecureArray plainText = "no more secrets";
    	QCA::SecureArray encrypted = publicKey.encrypt(plainText, QCA::EME_PKCS1_OAEP);
    	qDebug() << "encrypted:" << encrypted.toByteArray();
    	
    	QCA::SecureArray decrypted;
    	privateKey.decrypt(encrypted, &decrypted, QCA::EME_PKCS1_OAEP);
    	qDebug() << "decrypted:" << decrypted.toByteArray();
    }
    

    This works as expected.

    I am now thinking of using just the key file like this:

    void QcaTest::publicKeyEncryption()
    {
    	QCA::Initializer init;
    	
    	if (!QCA::isSupported("cert"))
    		QFAIL("Certificates are not supported.");
    	
    	QString privateKeyFile = QFINDTESTDATA("key.pem");
    	QCA::ConvertResult convertResult;
    	QCA::PrivateKey privateKey = QCA::PrivateKey::fromPEMFile(privateKeyFile, "test", &convertResult);
    	if (convertResult != QCA::ConvertGood)
    		QFAIL("Could not open private key.");
    	
    	QCA::PublicKey publicKey = privateKey.toPublicKey();	
    	QCA::SecureArray plainText = "no more secrets";
    	QCA::SecureArray encrypted = publicKey.encrypt(plainText, QCA::EME_PKCS1_OAEP);
    	qDebug() << "encrypted:" << encrypted.toByteArray();
    	
    	QCA::SecureArray decrypted;
    	privateKey.decrypt(encrypted, &decrypted, QCA::EME_PKCS1_OAEP);
    	qDebug() << "decrypted:" << decrypted.toByteArray();
    }
    

    Are there any disadvantages with this solution?


  • Qt Champions 2017

    Your idea was to encrypt using RSA public key and decrypt using the private key. If this is the case what you are doing correct. Just that you read the keys from key.pem.



  • @dheerendra said in Encrypt/decrypt data with QCA:

    Your idea was to encrypt using RSA public key and decrypt using the private key. If this is the case what you are doing correct. Just that you read the keys from key.pem.

    Yes, that's what I want to do.
    So I guess this is solved. Thank you very much for your help!


Log in to reply