之前二篇文章介绍了QCA框架的安装和配置,在这篇文章中我将开始编写一个基于数字证书的加密例程,用来讲解QCA框架的使用。其实QCA的应用是非常简单的,且在源代码发行包中也附带了大量的例子(在qca-2.0.3\examples目录中),基本上可以解决我们日常的加解密编程工作。

照例先介绍一下开发环境:

  • 操作系统:windows7 32位版本。
  • Qt SDK:4.8.5版本(安装路径:C:\Qt\4.8.5)。
  • QCA SDK:2.0.3版本。
  • OpenSSL:1.0.0g版本,QCA依赖库,并且用于生成一张数字证书文件。
  • IDE:NetBeans IDE 7.3.1 C/C++版本。

首先用OpenSSL生成一张测试用的数字证书,网上有一坨介绍OpenSSL生成数字证书的文章,所以我就不再重复介绍了,如果你很懒,不愿意去看文章自己生成数字证书,我这里提供了一个测试用的数字证书,以便你可以正常的运行本例程,在文章的最后我提供了整个例程的源代码,其中就包含了测试用的数字证书(在etc目录中)。接着我们打开NetBeans,新建一个Qt类型的应用程序项目。在我之前的一篇文章中介绍了使用NetBeans进行C/C++开发的文章,有兴趣的同学可以去看看,总体来说,在C/C++ IDE方面,NetBeans比Qt Creator和Eclipse要强点(VC++除外,因为我们用的gcc编译器)。

项目创建好之后大致的目录结构如下图所示:

(图一)

这里我们关注的是certificatecrypto.h和certificatecrypto.cpp文件,如下所示:

#ifndef CERTIFICATECRYPTO_H
#define CERTIFICATECRYPTO_H#include <QtCore/qdir.h>
#include <QtCore/qstring.h>
#include <QtCore/qbytearray.h>const QString CERT_FILE_DIR = "etc";class CertificateCrypto
{
public:explicit CertificateCrypto();virtual ~CertificateCrypto();bool encrypt(const QByteArray &in, QByteArray *out);QString toHex(const QByteArray &in);private:QDir m_certFileDir;
};#endif    /* CERTIFICATECRYPTO_H */

在头文件中我们定义了数字证书的存放路径,以及加密函数。接下去看实现类:

#include "certificatecrypto.h"#include <QtCore/qdatetime.h>
#include <QDebug>
#include <QtCrypto/qca.h>/*** 构造函数*/
CertificateCrypto::CertificateCrypto() : m_certFileDir(CERT_FILE_DIR)
{
}/*** 析构函数*/
CertificateCrypto::~CertificateCrypto()
{
}/*** 证书加密* @param in* @param out* @return */
bool CertificateCrypto::encrypt(const QByteArray& in, QByteArray* out)
{//1. 初始化QCAQCA::Initializer qca_init;QCA::SecureArray encrypt;//2. 检查系统是否支持QCA插件if (!QCA::isSupported("cert")){qDebug("对不起,当前系统不支持数字证书!");} else{QString cert_file = m_certFileDir.absoluteFilePath("server.cer");//3. 加载数字证书QCA::ConvertResult result;QCA::Certificate cert = QCA::Certificate::fromPEMFile(cert_file, &result);if (result == QCA::ConvertGood){//4. 检查数字证书有效期QDateTime before = cert.notValidBefore();QDateTime after = cert.notValidAfter();QDateTime now = QDateTime::currentDateTime();if (now >= before && now <= after){//5. 获取数字证书中的公钥QCA::PublicKey pub_key = cert.subjectPublicKey();if (pub_key.canEncrypt()){//6. 用公钥加密encrypt = pub_key.encrypt(in, QCA::EME_PKCS1v15);out->clear();out->append(encrypt.toByteArray());return true;} else{qDebug("对不起,当前数字证书不支持加密!");}} else{qDebug("对不起,当前数字证书已过期!");}} else{qDebug("对不起,加载数字证书失败!");}}return false;
}/*** 转换成16进制字符串* @param encrypt* @return */
QString CertificateCrypto::toHex(const QByteArray& in)
{return QCA::arrayToHex(in);
}

类的实现是非常的简单易懂,我不用多说什么,相信各位同学凭借代码中的注释就应该知道每段代码实现的意图了。这里仅讲解几点重要的关注点:

1. 在使用QCA之前,必须要对其进行初始化调用,否则QCA将无法工作,就是代码中的“QCA::Initializer qca_init”。

2. 在调用QCA相关加密算法之前最好做一次检查,看当前提供者实现是否支持该加密算法,例如代码中:if (!QCA::isSupported("cert")),就是检查一下是否支持数字证书,有同学肯定会问,如何知道isSupported函数中的那个算法字符串参数呢?其实在之前的文章中我们已经讲到过了,就是使用qcatool2工具,在命令行中输入“qcatool2 plugins --debug”,然后会显示中一大堆算法名称,isSupported函数中就是使用这个算法名称的字符串。如在我的开发环境中如下图所示:

(图二)

3. qca-ossl提供者的数字证书算法实现是支持多种方法加载证书的,在我的代码中是使用了文件加载方式,另外还支持字符串加载方式和字节数组加载方式,根据实际的应用环境可以选择不同的证书加载函数。

4. QCA返回的密文是QCA::SecureArray对象,所以要将其转换成字节数组(QByteArray)之后才能进行后续的处理。

5. 要编译并链接QCA库必须进行一些必要的设置,如下图所示:

(图三)

在项目属性对话框中点击“Qt”,在右边的框中选择“定制定义”旁的按钮,弹出定制定义对话框,点击“添加”按钮,输入“CONFIG += crypto”,最后点击保存。

大家是否还记得,在本系列的第一篇文章中我们定义过的crypto.prf文件(在%%QTDIR%\mkspecs\features目录中)。在这个文件中定义了QCA的头文件目录以及库文件目录。Qt在编译应用程序时会读取该配置文件,从而获取编译及链接的相关信息。

好了,现在我们可以运行程序了(其他的相关代码不再介绍了,都是一些Qt GUI的基础编程),如下图所示:

(图四)

程序显示一个主窗体和一个确定按钮,点击确定按钮,会在文本框中显示加密的字符串(明文为:“hello world!”),如下图所示:

(图五)

至此,我们的应用程序开发完成了,总体来说QCA的开发不是很困难,基本上API的设计是很友好的。非常适合从Java转型的Qt开发人员(包括我自己)。下一篇文章我们将介绍如何将QCA例程打包发布成脱离Qt开发环境的应用程序安装包,敬请关注。

提供本例程源代码的打包下载,共学习参考:qca_demo.rar

在C++ GUI Qt中使用QCA进行安全性编程之三相关推荐

  1. Qt中采用多线程实现Socket编程

    Qt中采用多线程实现Socket编程 Socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 本文介绍的是Qt中采用多线程 ...

  2. Qt中TCP服务端编程

    文章目录 1 Qt中的TCP服务端编程 1.1 TCP服务端编程介绍 1.2 Qt中的TCP服务端编程 1 Qt中的TCP服务端编程 1.1 TCP服务端编程介绍 网络中的服务端: 服务端是为客户端服 ...

  3. c gui qt 4编程第二版_一本专门学习PyQt5 GUI编程的书

    Python作为一个开源的解释型编程软件,在教学.科研.实际项目中用得越来越多.Python易学易用,程序资源丰富,在编程解决一些科学计算问题时比较实用,但是Python自带的Tkinter包设计GU ...

  4. 用事件队列解决GUI的操作顺序问题(Qt中处理方法)

    GUI操作顺序问题引发异常: 有时候我们使用写GUI程序的时候会遇到这样的问题:比如在程序中,建立了一个列表的GUI.这个列表是随着时间不断更新的,而且操作也会读取这个列表GUI的内容. 如果这个程序 ...

  5. QT中如何实现Thread与GUI的主线程连通

    QT中如何实现Thread与GUI的主线程连通 本文介绍的是QT中实现Thread与GUI主线程通,目前只会一种,采用信号槽机制. 通常情况下,信号和槽机制可以同步操作,这就意味着在发射信号的时候,使 ...

  6. Qt中 gui 模块和 widgets 模块的区别

    简述 在Qt5下,QWidget系列从QtGui中被剥离出去,成为单独的QtWidget模块.随着Qt Quick2的引入,QtDeclarative也逐渐和QWidget系列也脱离关系. 最终:在Q ...

  7. Qt中的TCP客户端编程

    文章目录 1 Qt中的TCP客户端编程 1.1 TCP客户端编程介绍 1.2 QTcpSocket的同步编程 1.3 QTcpSocket的异步编程 1 Qt中的TCP客户端编程 1.1 TCP客户端 ...

  8. Qt中多线程与界面组件的通信

    文章目录 1 多线程与界面组件的通信 1.1 通过信号与槽实现多线程与界面组件的通信 1.2 通过自定义事件实现多线程与界面组件的通信 1 多线程与界面组件的通信 有趣的问题: 是否可以在子线程中创建 ...

  9. Qt中的自定义模型类

    文章目录 1 Qt中的通用模型类 1.1 Qt中的通用模型类 1.2 Qt中的变体类型QVariant 2 自定义模型类 2.1 自定义模型类设计分析 2.2 自定义模型类数据层.数据表示层.数据组织 ...

最新文章

  1. 如何理解numpy.nan_to_num
  2. 调用加了SSL签名的WebService
  3. golang 函数指针相等比较
  4. range和xrange的区别
  5. sap相关性不能被编译_经典综述编译丨生物硝化抑制丨NAT PLANTS:现代农业中的氮转化和生物硝化抑制作用...
  6. Windows环境下多个tomcat启动方法
  7. 计算机二级晓云是企业人力,全国计算机二级Ms-Office精选真题试卷
  8. HTTP状态码大全(常见 HTTP Status Code 含义查询)
  9. linux 网桥配置命令:brctl
  10. 深夜读萧红《呼兰河传》
  11. Only the original thread that created a view hierarchy can touch its views. 是怎么产生的
  12. 百度的春晚战事:如何扛住腾讯、阿里都宕机的量?
  13. python中怎样在图片上画线段_python 实现PIL模块在图片画线写字
  14. AtCoder题解——Beginner Contest 170——F - Pond Skater
  15. 《2040大预言:高科技引擎与社会新秩序》——2.4 在芯片上建造大金字塔
  16. 二分法查找Unicode To GB2312转码表
  17. pat 1124 Raffle for Weibo Followers(20 分)
  18. 【专升本计算机】2021年甘肃省专升本计算机全真模拟试题(一)
  19. python爬取付费漫画_python selenium爬取kuku漫画
  20. 四轴飞行器入门——基础知识

热门文章

  1. 我为什么从一名文科生到算法工程师
  2. Flightradar24 让你实时跟踪全世界飞行航班
  3. 推荐三个优秀的国外HTML5网页设计网站
  4. windows service2008 2R 开启telnet
  5. 利用Image-Pro Plus计算图片裂缝面积的方法
  6. Jetson系列——罗技手柄F710模块
  7. 如何查看slice order
  8. 诺基亚n8和n9java_诺基亚N9和诺基亚800哪个好
  9. 数据存储——声音存储
  10. 日历公历农历C语言大作业,C语言编写一个带农历的万年历