gpgme库的编译和使用

序言
除非万不得已,请不要使用gpgme,openssl是更好的选择。原因有三,第一点,openssl能在网上找到很多例子,出错了很容易找到原因,而gpgme吗?呵呵,别看它用的多,但找到的都是gnupg命令相关的,除了stackoverflow能找到点。第二点,openssl封装的不算彻底,而gpgme呢?呵呵,傻瓜式的接口,极易上手,但你就基本了解不到算法了,第三点,你以为使用gpgme就使用一个库就可以了,呵呵,gpgme只不过是壳子,提供了API给你,没有gnupg,加密和解密就是空话。至于我为什么使用这个库,要不是客户,我肯定优先选择openssl。

介绍
大神请跳过这一段,这一段是以我自己的理解去描述加解密的内容。加解密的含义和作用我就不bb了,大概介绍一下。
加解密主要分为非对称和对称,简单理解,对称加密就是加密和解密所使用的密钥是一致的,非对称加密是加密和解密使用的密钥是不一致的,它会生成一对密钥(public key and private key),加密使用的是公钥,解密使用的是私钥。如果使用公钥和私钥的顺序颠倒过来,就是加签和验签过程。这是大概的一个描述,至于证书,摘要算法(哈希)、指纹等等,内容太多,如果不是专业,浅尝辄止即可。至于程序员,关键是如何使用。常见的加解密算法很多,对称算法比如:AES、DES等等,非对称算法比如:RSA、DSA、DH、ELG等等。不过算法离使用者还是有些遥远,所以就有了两种库,针对SSL协议的openssl和openpgp协议的gnupg。至于openssl,我就不多介绍了,资料很多。而gnupg,ubuntu自带了,可以用这个命令试一下,gpg --version。看看是否有内容输出。
咦,似乎有人有疑问了,gnupg和gpgme有什么关系呢???画个简单的图gnupg和gpgme关系图gnupg最终编译出来的是可执行程序,而gpgme编译出来的是一个库,这个库提供了简单的API供开发者使用。只不过这个库需要依靠gnupg的可执行程序才能实现加解密。

编译
编译前,请先到https://www.gnupg.org/download/下载gpgme、libassuan和libgpg-error的源码。libassuan和libgpg-error是gpgme的底层库。我不介绍ubuntu下的编译,因为ubuntu下的编译过程是傻瓜式操作。分别进libgpg-error、libassuan和gpgme的源码,直接./configure、make -j8、make install即可,一般不会出错。我介绍的是windows下的编译过程。
(1)这个库没有提供vs工程,应该是vs下编译不了的。
(2)考虑的就是mingw编译了。mingw64我没试,我试的是mingw32。ubuntu下使用mingw交叉编译的方式试了一下,会出错,我放弃了。
(3)所以考虑的是windows下使用Cygwin编译,因为编译出来的也是win32的库,很遗憾,cygwin编译libgpg-error和libassuan都没问题,编译gpgme会出错,看提示好像是链接不到libgpg-error和libassuan的动态库,而cygwin下也编译不出libgpg-error和libassuan的动态库。谷歌了一下原因,太复杂了,放弃了。不是我不愿意调查,第一是项目时间有限,第二是编译库这种东西,往往解决了一个麻烦还来另一个麻烦,万一碰到死胡同就意味着前功尽弃。
(4)最后的方法是使用MSYS2编译。它有三个终端,MSYS2 shell、mingw32 shell和mingw64 shell。除了MSYS2 shell,其他两个终端对应的安装目录的文件夹内是不存在什么编译环境的,由于我们需要在mingw32编译,所以需要自己安装编译环境。
有两种安装方式:一,缺啥补啥,使用pacman -S mingw-w64-i686-****(自己补充)
,类似于apt,速度太慢可以换源。二,如果装了QT的,直接将tool目录下的mingw32文件夹替换掉MSYS2下的mingw32目录即可。
选完环境,下面开始编译。

马上应该会遇到一个错误,namespace相关的,具体编译哪个库的时候我忘了。此时不要慌,输入以下命令,gawk --version。如果显示的版本是5.0.0及以上,那就找到原因了。去网上下载gawk4.2.1的源码。此时一定要打开MSYS2 shell去编译gawk4.2.1,因为使用mingw32 shell编译gawk4.2.1会出错,至于为什么?我不知道,试出来的。编译方式还是傻瓜式操作,我不赘述了。编译安装完成,gawk --version试一下,版本4.2.1
,恭喜你,可以继续之前的gpgme的编译了。下面应该是没什么问题了。编译完成,可以生成gpgme.h、libgpgme.a和libgpgme.dll.a这些东西。

调试
现在魔鬼来了,当你使用自己编译的gpgme库和在ubuntu下已经正常工作的程序测试时,你以为一切接近尾声,其实刚刚开始。
我列一下我遇到的问题:
(1)程序加密时提示Invalid crypto engine。这个error在调用check engine 的API时会出现,是因为你的程序没有检测到gnupg。前面说了gpgme只是个壳子,gnupg才是干活的。
(2)程序已经检测到gnupg,但是如果链接的是自己编译的gpgme库,程序会直接段错误,打出一堆乱码和_gpgme_io_selectw***,而且段错误是在库的内部发生,我尝试用gdb和printf也看不出来为什么,猜测可能是底层IO操作存在问题。

错误的解决方法
(1)针对Invalid crypto engine,我尝试了gpgme的manuals(https://www.gnupg.org/documentation/manuals.htm)下的很多方法,比如set engine info、set global flag里的gpgconf和gpg属性,然并卵,无效。
(2)针对段错误,我以为是因为gnupg和gpgme的编译环境不一致造成的,然后gnupg和gpgme都编译一遍,然并卵,无效。

正确的方法:
(1)不要使用MSYS2编译出来的gpgme库,./configure --help看一下,其实它还可以编译gpgme-glib库,请使用这个库。你嫌麻烦的话,这个库也不用自己编译,使用pacman -S mingw-w64-i686-gpgme安装,然后在lib目录下就可以找到它了。段错误问题就可以解决了。
(2)至于Invalid crypto engine问题,使用set global flag的w32-inst-dir属性,value那个参数就传入gnupg bin的路径。
gnupg安装的话有三种方式,
(1)下载源码自己编译,最麻烦,也最容易出错。
(2)下载gpg4win,这个是可执行程序。安装完成后有两个文件夹,gpg4win和gnupg,第二个就是你需要的。gpg4win的软件层次其实类似于你自己的程序,它也是使用gpgme库的。
(3)使用pacman -S mingw-w64-i686-gnupg安装或者直接使用MSYS2 bin目录下自带的gnupg。

无论哪种方式,windows下请在自己的程序使用set global flag的w32-inst-dir属性指定gnupg的安装位置,绝对路径和相对路径都可以,防止各种奇妙的事情发生。

对了,pinentry这个也是少不了的。因为生成密钥或者解密时,会跳出一个提示框,让你输入密码,这个可视化界面是由pinentry支持的。一般gnupg安装方式的(2)会自带pinentry,(1)的话需要自己编译pinentry,(3)的话需要使用pacman -S mingw-w64-i686-pinentry安装pinentry,这个需要下载qt5-core相关的环境,1个G的大小。推荐方式(2),最简单。

还有最重要的一点,Windows下的程序,加密时如果是二进制数据相关的,请加上gpgme_set_armor这个属性,ubuntu下无所谓的,Windows下如果不加这个属性,你会发现解密完的数据和源数据不一致,md5sum算一下就看出来了。

哎,一把辛酸泪,誰解其中味。远离gpgme,珍爱生命。拥抱openssl,重获新生。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_26654257

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值