Ubuntu Eclipse中Pairing Based Cryptography编程配置详解

来源:互联网 发布:知乎手机如何提问问题 编辑:程序博客网 时间:2024/06/05 21:12

前言

我的技术博客从新浪搬家到CSDN的时候,有一些小的感觉没什么用的博客都删掉了… 结果,今天有位朋友给我微博留言,表明其正在研究Pairing-Based Cryptography Library函数库,发现我相关的这篇博客被我删除了,问我能否回复一下… 在此要给开发PBC以及密码学的朋友们说声抱歉哈!每一篇博客的价值并非是总访问量问题这么简单,每一篇博客都有不同的受众群体。因此,我应该把我认为有价值,有用的,可以帮助到大家的博客都搬移过来。

因此,我决定在CSDN我的技术博客中恢复这一篇对做密码学相关朋友有帮助的博客。如果因为我删除博客而对朋友们有一定的影响,我再次向大家道歉!

另外,我实验室的师弟师妹们根据我的Guideline配置后,也遇到了一些问题,再次我也一并写在这一篇恢复博客中,供大家参考。因为每一台电脑的情况都有所不同,因此即使是严格的技术博客,也可能无法考虑到各种情况,希望大家见谅。如果有任何问题,欢迎给我发送邮件,或者直接在博客下面留言,我将尽我所能帮助到大家,如有必要,我们可以进一步在QQ上,微信上,甚至当面交流:)我的邮箱是:footman_900217@126.com。

主观动机

我自己是搞密码学的,实现的时候免不了用用Linux C;有时候也玩点GPS、北斗接收机什么的,再有时候玩玩Android什么的,没准过几天还能玩玩Windows8(刚刚从MSTC那边定了一个SurfacePro,这是转入.NET开发的节奏么…)。除了Windows这个蛋疼的平台(唉,要不是Windows上面有一个传说中的Microsoft Office和各种游戏,我早就彻底用Ubuntu了!LaTeX部分解决了这个问题,但是大多数人还是得用Word,PPT,Visio什么的吧,这个真心没办法),前面几个还都是挺好玩的。

言归正传,密码学里面有个东西叫做双线性对(Bilinear Pairing),只要是最近10年做密码学的人肯定知道这个推动密码学发展的数学函数了。Stanford网络安全实验室(负责人叫做Dan Boneh,是我最崇拜的密码学家,没有之一!)在Linux平台下用C语言开发了一个叫做PBC(Pairing-Based Cryptography) Library的东西,实现了双线性对,并且是遵守开源协议的,因此成为了密码学家验证方案正确性,以及测试方案效率的不二选择。但是这个库对于刚刚接触Linux的朋友们来说还真挺难驾驭的,尤其是习惯在IDE环境里面开发的朋友们来说,特别是喜欢在Eclipse开发的朋友们…这PBC库的使用满足了EclipseCDT开发的所有问题,列举如下:

  1. PBC安装之前要先安装GMP,而如何从源代码安装软件是使用Linux必须要学会的。
  2. PBC按照默认配置安装后,so和a文件存放于/usr/local/lib/文件夹中,一般的软件也都是这样。但是头文件放置在/usr/local/include/pbc/文件夹中,也就是说PBC库在/usr/local/include中建了一个文件夹,然后把头文件放在了里面。这一下挡住了很多想在Eclipse下用PBC开发的人,因为不配置的话Eclipse找不到这个头文件的目录。
  3. 如果想运行PBC中的example,都需要在main函数传参数,也就是把常数文件路径通过main传参。在Terminal中给main传参大家都会,但是如何在Eclipse中给C的main函数传参?这又挡住了很多人。
  4. 根据PBC官网的说法,因为PBC的实现中有个Bug,因此需要给Linux C编译器多传入一个参数。这个参数怎么在Eclipese里面配置呢?这进一步把朋友们逼疯了…
  5. 密码学中还有一个非常知名的库,就是OpenSSL中的Crypto库。这个库几乎包含了所有的密码学相关函数。但是想在Eclipse中应用OpenSSL中的Crypto库开发比PBC更繁琐一些,这是因为默认安装OpenSSL后,其Crypto库竟然根本不在/usr/local/lib里面,而是直接在/usr/local/目录下面建了一个SSL文件夹,然后把所有的头文件和库文件放在这个文件夹里面。

因此,我觉得很有必要写一篇博客总结一下Eclipse中C开发所需要的各种配置。一方面是给自己留一个笔记,另一方面以后实验室再来师弟师妹就不用自己再讲一遍了,也是为我节省点体力吧:)

客观动机

最近自己在搞Android上面的PBC开发,写个Server端写个Client端,Server端是Java+ Linux C混合编程;Client端是Java+ NDK C混合编程。客观条件也得让我把整个配置环境跑通吧!

内容介绍

本篇博客不会详细介绍的内容

(1)Eclipse + CDT的安装

Eclipse的安装太简单了,Ubuntu下面直接apt-getinstall eclipse就行了,如果找不到安装包请修改Ubuntu的软件源。不过apt-get所安装的Eclipse版本比较旧,如果想安装新版的Eclipse,请参考Eclipse官方网站给出的安装方法。Eclipse官方网址:http://www.eclipse.org/。

CDT的安装也相当简单,请参考EclipseCDT插件官方网站给出的安装方法。

(2)GMP以及PBC的源代码安装

经典三部曲:./configure,make,makeinstall。GMP官方网址:http://gmplib.org/;PBC官方网址:http://crypto.stanford.edu/pbc/。

(3)JNI技术以及NDK技术

这里不会讨论JNI技术本身和NDK技术本身。不过,如果以后大家需要的话,我会提供一个比较通用的JNI封装库和一些我写JNI的经验,没准可以帮助到大家。当然啦,也没准会误导大家…

(4)GMP、PBC以及OpenSSL在Android上面的移植方法

这个还是不写在博客里面了…据我在网上搜索,还没有介绍PBC如何移植的方法,可能是因为这个库本身不会有太多人用吧。PBC的移植方法和导航软件中常用的FFTW库移植方法很像,FFTW库网上有很标准的移植方法介绍,而且经过测试是正确的,大家可以自己移植一下试一试。GMP库以及OpenSSL库在开源社区里面都有移植成功的现成库,大家可以直接拿过来用,亲测没问题!

PS:这里要跟想用Java开发PBC的朋友们补充一下,PBC有个相关的东西叫做jPBC,官方网站上说是开发了一个能用Java直接开发PBC的函数库。当时我自己也兴奋了半天(不用移植PBC了啊!),结果研究了好久还是不知道这玩意怎么用。官方网站还给出了一个Android的实例apk,说已经可以在Android上面调用PBC了,但是没给出移植代码,我自己测试了一下,好像是可以用的,但是可以用管什么,自己调不了啊!一怒之下自己移植了一个,终于可以用了…

PPS:这篇博客写完后,我现在一直在用jPBC了,因为确实封装的非常好啊!而且,现在jPBC确实可以在Android上面使用,不过需要调一下。如果我调通了,可以跟大家分享一下如何使用jPBC在Android上面进行开发。我可以确信,jPBC的封装比我自己移植的PBC好用!

PPPS:在我配置、移植、编程过程中遇到过很多问题,也各种Baidu、Google过,结果发现大多数的搜索结果都不能用。最让我气愤的是,不能用的还被很多人一遍一遍的转发。在此我想呼吁一下喜欢写技术博客的朋友们,转发当然没问题,但请大家务必自己测试一下!有的时候原文可以用,但是在别人的电脑上面可能因为操作系统问题、环境问题等等不能使用,需要进行一些额外的配置,还请补充一下,造福大家嘛。

本篇博客将要介绍的内容

(1)一个bls.c在Eclipse下的运行实例配置

走下来整个配置流程,Eclipse中C编程的配置基本上就没问题了。个别有关JNI和NDK的问题我会在后面补充。

(2)一个Java JNI中Java+ C混合编程的配置参考

这种混合编程如果一步一步截图问题实在太多了,我就拿出了一个自己弄好的项目,把配置一个一个截图放上来,并且给出说明。如果朋友们遇到一些特定的问题,可以给我留言,如果能帮助到大家我会尽量回复的。

(3)总结

主要说明Eclipse中C配置的原理,Eclipse中JNI的原理。

BLS签名方案的运行实例

准备工作

作为开发人员,想使用一个函数库,当然要先阅读以下函数库的说明文档了。下图是有关PBC库使用以及配置的说明,是从PBC官方网站下面截图来的。

也就是说,如果想在自己的Code中应用PBC库,要给出那么多的配置。没关系,我们一步一步来。首先,我们用Eclipse新建一个C工程。这里注意,实际上可以选择建立CProject或者C++ Project。如果选择的是C Project,默认就是用gcc编译;如果选择C++Project,默认选择g++编译。

之后,选择Empty Project,在后面选择用Linux GCC编译,因为我们的程序是要直接运行在Ubuntu系统下的。crossgcc是交叉编译,这个大家都懂的~

选择完毕后直接点击Finish就可以了,不用再进行其他的配置。完毕后,我们从PBC源代码中把bls.c文件import进来,或者在工程下新建一个bls.c源文件,然后把PBC源代码中的bls.c直接粘贴过来就行了。粘贴完毕后编译一下,各种报错…

有关compile的问题

我们首先看第一个错误,这是include文件没有找到。这个错误对应的就是PBC的include文件存放问题了。右键点击项目,选择Property...,在打开的对话框中找到C/C++ Build中的settings,在GCC Compiler的Includepaths中把头文件的目录添加进来,如图。

这样就解决了有关compile的问题。

有关link的问题

完成上一节介绍的步骤后我们关闭对话框,再编译,会发现include的报错已经没有了,但是变成了别的报错,如图。

这一堆错误实际上是因为我们没有添加库文件。还是打开项目的Property对话框,同样在C/C++Build中的Settings,在GCCLinker的Libraries中,分别将库文件pbc以及库文件路径添加其中。注意,库文件前边不用加lib,比如库文件叫做libpbc.so或者libpbc.a,那么Include Libraries中添加pbc即可,如图。

完毕后,我们关闭,再编译,所有的错误都消失了!不过,观察bls.c的main函数,我们会发现main要求我们将常数文件存放路径通过main函数传递进来。这个如何设置呢?右键点击项目,选择Run->RunConfiguration...,选择Arguments标签页,在下面把传递的参数打进去,如图。


完成后点击Apply,再次运行程序,就能得到bls.c正确的输出了,如图。

到此,有关bls.c的一个实例就介绍完毕了。

有关PBC Bug的问题

在我师弟师妹们配置的时候,出现过一个别的错误。具体的错误截图我实在是找不到了…如果按照我上面的配置,还是有问题的话,可以看一下PBC官方网站的一个解释:

You may be wondering why there’s a pbc on the end of the -Ioption but not the-L option. This is PBC’s fault: instead ofhaving a single header file named "pbc.h", there are many otherheader files that the developer never needs to know about, and to stopthem messing up the include directory, all the PBC header files areplaced in a separate subdirectory of their own. Other libraries alsofollow this convention.

It might seem pointless to have an rpath option. Why nothave the binary automaticallysearch for the library in the directory specified by the-L option? While this may suit you now, situationswhere this behaviour is undesirable can easily occur.For example, say you don’t have root access on the system you developon and the "Foo" library is not installed (so you need the L option),but on the target systemsthat your binaries end up on, the "Foo" library is always foundin a standard location (so you don’t want the rpath option). Or maybe"Foo" is located somewhere special on the target machine, soyou want rpath to point to a different directory altogether.

因此,大家需要弄出-I和-rpath参数来。这两个参数的设置在Eclipse中的Properties->miscellaneous项设置,直接把命令粘贴过去即可。

有关取消BLS.c中main函数传参的问题

在实际开发中,我们一般都不太希望在main函数直接传参,这是因为如果将这些密码学方案移植到手机端后,这个工程就和Java工程合并在一起了。因此,这个工程需要在main函数中自己找到文件路径,然后读取参数,再进行初始化。实际上,在PBC中并没有给出这样的设置。一种比较好的解决方法是稍微修改一下PBC中的源代码,使其支持直接根据手写的文件路径来读取参数,而不用从main函数中传参来获得文件路径了。

需要修改的文件为include/pbc_test.h文件。我们只需要修改pbc_demo_pairing_init函数,让其传一个文件路径进来,根据文件路径读取即可。这样,在main函数中,我们只需要写死一个char s[]变量为文件路径,然后将char s[]传给pbc_demo_pairing_init函数即可。修改后的pbc_demo_pairing_init函数如下。

static inline void pbc_demo_pairing_init(pairing_t pairing, char* filename) {  char s[16384];  FILE *fp;  fp = fopen(filename, "r");  if (!fp){  pbc_die("error opening %s", filename);  }  size_t count = fread(s, 1, 16384, fp);  if (!count){  pbc_die("input error");  }  fclose(fp);  if (pairing_init_set_buf(pairing, s, count)) pbc_die("pairing init failed");}

修改后的调用函数如下。

//char* c_filepath = ...;pbc_demo_pairing_init(pairing, c_filepath);

这样就可以得到我们想要的结果了~要注意的是,文件路径不能够过长,不过16384这么长的路径肯定已经够了… 实在不够大家就再修改参数!

gcc中各个参数在Eclipse中的对应

其实,细心的朋友们如果仔细观察Eclipse编译、链接、运行时候的输出,以及Eclipse中项目属性的描述后,就能很容易发现其中的关键点。实际上Eclipse的CDT和其他的IDE是一样的,都是给用户提供一个界面帮助用户编程,实际上还是在后台执行例如gcc、make等等的命令。我们观察报错的那几张图,实际上Eclipse在后台执行了下面的命令:gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF”bls.d”-MT”bls.d” -o “bls.o” “..bls.c”
也就是说,Eclipse执行的命令和我们在Terminal中执行的编译命令是一样的。我们在Eclipse中的配置,实际上都是为了在这一行命令后面加东西。在上面的配置中,GCCCompiler中的include页面加的是-I;GCC Linker中的Library页面加的是-l;LibraryPath页面加的是-include。我们把这几个命令对应起来,实际上就是PBCManual中所说的-I,-l以及-include。
明白了这一点,我们在后面的开发中,如果遇到了什么问题,可以在gcc命令中找对应的参数,然后在Eclipse项目配置中,找到对应的参数添加地点,把参数加进去就行了。举例来说,比如我们要使用OpenSSL中的Crypto库,我们就在GCCLibrary中的Libraries添加crypto,然后再LibraryPaths中添加/usr/local/ssl/lib即可。

有关Java JNI在Eclipse中的开法以及Android中NDK在Eclipse中的开发

Eclipse对于Java的支持是前所未有的(毕竟Eclipse本身就是Java开发的嘛),既然对Java有着非常优秀的支持,那么对于Java的JNI技术当然也有非常好的支持了。

实际上,Eclipse是支持Java +C的混合编程的,而且可以做到一个工程分别是Java工程和C工程。也就是说,如果需要在C下面开发,那么就切换到C/C++模式;如果是Java工程,那么就切换到Java模式开发即可。不过这样混合开发需要一点点的设置。设置什么呢?很简单,就是设置让Java工程如何找到C工程编译出的so文件,并在Java端执行。毕竟我们自己虽然知道so文件存放在何处,但是JRE不知道也是白搭。下面分别讲解这一部分的设置方法。

将Java工程转换为C工程

在Eclipse菜单中选择New->Others,在弹出的对话框中选择Convert to a C/C++ Project,如图。

点击Next,后面的步骤中要注意几点:

(1) Project Type不是Empty Project了,而是StaticLibrary,毕竟我们这里要编译成的是一个so文件,供Java调用嘛。

(2) 如果要在Ubuntu下面运行,仍然选择Linux GCC编译器。

点击Finish以后,Eclipse就会把这个Java工程转换为一个C/C++工程。接下来,可以像上面介绍的一样,在C环境下开发StaticLibrary了。

以例子说明Static Library的配置

我以一个例子来说明StaticLibrary的配置。我的这个例子是我开发的一个程序的Server端,是Java程序,应用JNI调用PBC实现双线性对运算,同时应用JNI调用Crypto库实现sha1的运算。

首先,我们用的是GCC编译器,所以Properties中的GCC C++Compiler的配置对我们来说完全没有用。如果大家不确定用的到底是GCC C还是GCCC++,可以都配置一遍,反正就是点点鼠标的事情嘛。 

JNI中和一般C程序最大的区别就是,JNI中gcc编译命令中需要加入-fPIC参数,否则会报错,加这个参数的方法如下图。另外,下图中还显示了整个gcc的参数,实在是好长…所以用惯了Eclipse,就不用每次都在Terminal中敲入那么多的命令,也不用自己写make文件了哈。


includes中,加入pbc,ssl头文件以外,还有一个重要的头文件就是JNI的jni.h头文件。如果使用apt-getinstalljava等类似的命令安装JDK的话,这个头文件的位置是/usr/lib/jvm/java-1.6.0-openjdk/include。其中,java-1.6.0-openjdk是系统中java的版本号,大家可以自己看一下自己文件系统的目录,看看自己的实际目录是什么,一般来说不同时期安装的JDK目录都有所不同。

仅仅添加jni.h,直接编译的话Eclipse还是会报错。还需要添加/usr/lib/jvm/java-1.6.0-openjdk/include/linux这个头文件目录。具体报错内容是什么我确实记不清了,朋友们如果自己遇到问题可以留言帮我补充下哈。

GCC C++Linker中可以看到链接所加的所有参数,如下图。

Libraries中需要加入gmp,crypto,以及pbc。因为系统默认目录中没有crypto的目录,因此要在下面的Library search path中增加/usr/local/ssl/lib目录。注意,有的系统可能自己连/usr/local/lib都找不到,要在Library search path中把这个默认的目录也加入进来。

完成了上述步骤后,就可以开发、编译、生成so文件了。so文件生成在工程目录下面的Debug文件夹下面。然后,当我们开开心心地切换到Java模式,将Library引入,运行程序以后发现…竟然抛异常!抛异常的原因是系统找不到staticlibrary。这是因为我们没告诉JRE这个工程去哪里找so库。

右键点击项目,Property,弹出的对话框中选择Java Build Path,在Libraries选项卡中有一个叫做Nativelibrary locations: (None)。把这个location改成Debug就可以了。

这样,JRE就可以找到so库存放的位置,并且正确地调动so文件,执行Native Code了。

有关Android NDK

AndoridNDK也可以按照类似的配置进行。不过有一些区别。Android NDK的Native Code代码编译并不是用LinuxGCC的,而是用ndk-build编译的,因此要在属性对话框中将编译器设置为ndk-build。另外,Android中,是不用设置NativeLibrary的位置的。我们只需要在工程文件目录下面建立一个jni文件夹,并且把什么sourcecode、Android.mk、以及Application.mk编写完毕后一股脑放在里面,然后直接执行ndk-build。因为Android.mk中会写明工程名称,所以ndk-build会自己在工程文件夹下面建立obj文件夹以及libs文件夹,并且把编译好的so文件放入其中,而且可以自动将库函数加入到Android应用程序中。

具体的配置过程我实在是有点忘了,在下次开发Android +C混合编程的项目时我会记得一步一步截图放在博客中,供大家参考。

这篇碎碎念的博客就写到这里了。如果大家有任何有关Android NDK、Java JNI、EclipseC编程配置的问题,欢迎在下面留言,我很高兴能和全国各地的朋友们一起讨论好玩的技术!

0 0