編輯:關於Android編程
我在前面的一片博客中,介紹了jPBC 2.0.0在PC平台上面的配置和測試。既然jPBC是Java平台上面實現的,那麼jPBC能不能在Android這個以Java為主要語言的平台上運行呢?這樣一來,各種在jPBC上撰寫的有關雙線性對的函數就都能夠在移動終端上面用了。我個人的想法就是把最新的密碼學算法應用到工程裡面,而這確實是我想法的一個很好的跨越。因此,我在第一時間公開整個配置的過程以及我測試的方法,以供廣大國內密碼學研究者們進行嘗試。整個配置過程實際上是非常簡單的,這也要感謝jPBC庫的編寫者們的辛勤工作。在整個配置過程中,我幾乎可以確定,jPBC的開發者們在2.0.0版本中完全拋離了GMP庫和PBC庫,而是將整個PBC在Java上進行了完整的實現。而唯一沒有實現的部分,也就是橢圓曲線常數產生部分,作者也使用了相同的配置格式,以使得PBC中使用的橢圓曲線常數可以在jPBC中直接使用。
首先用到的當然是Android的開發工具啦。我使用的是Windows下面的ADT工具。這個工具已經被Google統一打包。也就是說,現在大家開發Android的時候,再也不用下載Eclipse,下載Android SDK,下載Android ADT,進行各種復雜的配置後才能使用了。Google將整個開發工具集成在了一起。這個集成工具的下載地址為:http://developer.android.com/sdk/index.html。裡面包含了包括Eclipse,Android SDK Manager,Android ADT在內的全套工具。
然而,如果是Linux平台下面的開發者,雖然Google也提供了Linux下面的Android打包開發工具,但是我建議大家不要使用這一打包工具,而是手動進行一步一步地配置。實際上,如果大家在網上進行檢索,會發現網上已經有很多很多的人在抱怨Linux下面Android打包開發工具的各種問題。所以,本著不給自己找麻煩的初衷,大家還是老老實實手動配置吧~
jPBC 2.0.0也是必不可少的。其官方網站為:http://gas.dia.unisa.it/projects/jpbc/index.html。需要指出的是,雖然網站中專門有一項是Android,但是裡面沒有給出任何配置或者使用的方法,有的只是下面的一段話:
JPBC runs out of box on Android (2.1+ version).
Download the following
APK to benchmark JPBC on your terminal. Once the benchmark is finished the results can be found on the external memory in a file called "benchmark.out".
If you don’t mind it sending me the results with a description of the characteristics of the terminal used pleasecontact me.
所以如果大家想使用Android jPBC,確實需要自己摸索一下怎麼配置,這也是我寫這篇博客的根本目的。同時,這一段話也可以讓我們確信jPBC是可以在Android上面運行的,畢竟連APK都已經有了嘛~
我們首先嘗試將jPBC中提供的APK文件恢復成工程文件。我們將分三步介紹恢復的方法:整理並准備需要的文件、Android-jpbc工程的建立和配置、運行Benchmark並顯示結果。
下載好jPBC 2.0.0的源文件後,解壓,觀察一下解壓的結果。我們可以發現,在解壓文件中有個文件夾名字為jpbc-android,這裡面存放了一些源文件,同時也存放了打包好的APK文件。原文件中包括了APK文件中使用的resources,有icon、layout、甚至可以找到AndroidManifest.xml。同時,在src文件中可以找到APK工程中需要的三個java源代碼:AndroidBenchmark.java、Benchmark.java以及JPBCBenchmarkActivity.java。在asserts文件夾下,存放了4個用於測試的橢圓曲線常數Properties:a.properties、d159.properties、d201.properties,以及d224.properties。這四個文件也是回復APK工程的必要文件。以上這些就是jpbc-android裡面所需要的全部文件了。
對於jPBC 2.0.0中的jar文件夾,裡面的兩個必要jar文件也是我們需要的library:jpbc-api-2.0.0.jar和jpbc-plaf-2.0.0.jar。
好啦,所有必要的文件都准備完畢,開始進行工程的建立。
1. 在Eclipse的Android開發環境中建立一個新的空工程。在我的測試中,我的工程名稱為Android-jPBC。
2. 將給出的AndroidManifest.xml引入到工程中。
這一步比較簡單,大家可以直接打開工程中的AndroidManifest.xml文件,然後用jpbc-android文件夾下面的同名文件對此文件進行覆蓋,當然也可以使用其他任意的方法。修改結果如圖。在此跟大家道個歉,我截圖的時候正好QQ上有一個好友上線提醒了… 為了保護朋友的隱私我把QQ上面的信息抹掉了,這也是這個圖裡面我唯一手動改動的部分。

AndroidManifest.xml修改後,我們會發現系統有個報錯,說找不到icon文件。這個是Android新版本的問題。在舊的Android版本中,程序的默認圖標就為icon。而在新版本的開發環境中,圖標名稱已經變為了ic_launcher了。因此,我們只需要在源代碼中修改這一部分,把名稱改為ic_launcher。或者把圖標的源文件名稱修改為icon,這兩種方法都可以。我使用的是第一種方法,修改結果如圖。大家可以看到,系統已經不報錯了。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGltZyBzcmM9"/uploadfile/Collfiles/20140517/2014051709103196.jpg" alt="\">
3. 引入其他必要的文件
我們還需要引入的文件有:三個源代碼文件,layout文件,assert中的四個橢圓曲線常數文件, 以及必要的jar文件。
我們首先將三個源代碼文件引入到工程中。引入結果如圖。我們可以發現,引入後系統報了很多錯誤,這是因為其他一些必要的文件還沒有引入成功。

隨後,我們分別更新layout文件、asserts文件以及jar文件。layout文件的引入和AndroidManifest.xml文件引入方法相同,在此就不再重復說明了。直接看圖:

asserts文件引入方法很簡單,直接將四個Properties文件復制到asserts目錄下,然後在Eclipse工程中刷新即可。需要注意的是jar文件。引入的方法是,在libs文件夾下點擊右鍵->import,然後選擇兩個文件即可。注意,大家不需要再按照PC上面jPBC的配置方法,在工程的Properties下面進行多余的設置了。因為Android默認會將libs文件夾下面的全部文件作為自己jar庫的一部分。配置的結果如圖。

至此,所有的配置就全部搞定了。大家注意,與以前的jPBC 1.2.1不同的是,jPBC 2.0.0的配置沒有涉及到任何有關Native Library的內容。也就是說,jPBC的編寫者們已經把PBC的所有核心功能都寫在了Java中,沒有涉及到任何原始PBC的調用,這極大地增強了jPBC的可移植性。同時,這也使得jPBC在Windows下面進行開發稱為可能。
所有內容配置完畢後,就可以運行啦。我們將手機連接電腦後,run這個工程即可。隨後,手機端會彈出如下圖所示的界面。

中間的iteration是測試的總次數。為了較快地給大家展示測試的效果,我這裡面只讓他運行一輪。點擊Benchmark後,程序將進行測試。等待一段時間後,程序會體制Benchmark已經測試完畢,測試結果已經輸出。
那麼,測試結果輸出到哪裡了呢?jpbc-android默認將輸出結果放置在Android內置SD卡中的根目錄下。實際上,測試完畢後我們可以在SD卡根目錄下面找打一個叫做benchmark.out的文件,這個文件存儲的就是測試結果。jpbc-android的測試結果輸出格式是html格式,因此大家可以用IE浏覽器等各種浏覽器直接打開這個文件,查詢測試的結果,如圖所示。

Benchmark的測試結果只能顯示時間等信息,那麼jpbc-android到底能不能成功運行呢?我現在將以前博客中撰寫的BBGHIBE方案也移植到Android中,看看能否得到正確的結果。
BBGHIBE中涉及到的源代碼幾乎不需要做任何修改,只有兩個地方需要特別注意:
1. 在PC中,輸出的方法是System.out.println,而在Android中,推薦的輸出方法是Log.i。因此,所有的System.out.println都需要改成Log.i的形式,舉例:
Log.i(tag, "Infor - encrypt: the generated random message is " + message);
BBGHIBEMasterKey msk = bbgHIBE.Setup("assets/a.properties", 7); 

package cn.edu.buaa.crypto;
import android.util.Log;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
public class BBGHIBE {
public static final boolean isDebug = true;
private static final String tag = "BBGHIBE";
private Pairing pairing;
private int MAX_DEPTH;
//Public parameters
private Element g;
private Element h;
private Element[] u;
private Element E_g_g;
/**
* System setup algorithms, takes the max depth of hierarchy as input, and outputs the master secret key
* @param perperties The file name of the elliptic curve parameters
* @param D Maximal depth of hierarchy
* @return Master Secret Key
*/
public BBGHIBEMasterKey Setup(String perperties, int D){
// Generate curve parameters
pairing = PairingFactory.getPairing(perperties);
this.MAX_DEPTH = D;
//generate alpha
Element alpha = pairing.getZr().newRandomElement().getImmutable();
// Generate public parameters
this.g = pairing.getG1().newRandomElement().getImmutable();
this.h = pairing.getG1().newRandomElement().getImmutable();
this.u = new Element[this.MAX_DEPTH];
for (int i=0; i= secretKey.identityVector.length);
//the identity vector for the secret key should match the receiver's identity vector
for (int i=0; i
BBGHIBEActivity.java
package cn.edu.buaa.crypto;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class BBGHIBEActivity extends Activity implements View.OnClickListener {
private static final String tag = "JPBCBenchmarkActivity";
private Button benchmark;
/**
* Called when the activity is first created.
*/
public void onCreate(Bundle savedInstanceState) {
// Init UI
super.onCreate(savedInstanceState);
setContentView(R.layout.bbghibe);
benchmark = (Button) findViewById(R.id.button);
benchmark.setOnClickListener(this);
}
public void onClick(View view) {
if (view == benchmark){
TestBBGHIBE.testBBEHIBE();
}
}
}
BBGHIBECiphertext.java
package cn.edu.buaa.crypto;
import it.unisa.dia.gas.jpbc.Element;
public class BBGHIBECiphertext {
Element C_0;
Element C_1;
Element C_2;
}
BBGHIBEMasterKey.java
package cn.edu.buaa.crypto;
import it.unisa.dia.gas.jpbc.Element;
public class BBGHIBEMasterKey {
public Element alpha;
}
BBGHIBESecretKey.java
package cn.edu.buaa.crypto;
import it.unisa.dia.gas.jpbc.Element;
public class BBGHIBESecretKey {
public String[] identityVector;
public Element K_1;
public Element K_2;
public Element[] E;
}
TestBBGHIBE.java
package cn.edu.buaa.crypto;
import android.util.Log;
public class TestBBGHIBE {
private static final String tag = "TestBBGHIBE";
public static void testBBEHIBE() {
BBGHIBE bbgHIBE = new BBGHIBE();
BBGHIBEMasterKey msk = bbgHIBE.Setup("assets/a.properties", 7);
String[] testI1 = {"Depth 1"};
String testI2 = "Depth 2";
String testI3 = "Depth 3";
String testI4 = "Depth 4";
String testI5 = "Depth 5";
String testI6 = "Depth 6";
String testI7 = "Depth 7";
String[] receiver = new String[7];
receiver[0] = testI1[0];
receiver[1] = testI2;
receiver[2] = testI3;
receiver[3] = testI4;
receiver[4] = testI5;
receiver[5] = testI6;
receiver[6] = testI7;
String[] ciphertextIV = new String[7];
System.arraycopy(receiver, 0, ciphertextIV, 0, 7);
//KeyGen for depth 1
if (BBGHIBE.isDebug){
Log.i(tag, "Generate secret key for user at depth 1");
}
BBGHIBESecretKey SKDepth1 = bbgHIBE.KeyGen(msk, testI1);
//Delegation for depth 2
if (BBGHIBE.isDebug){
Log.i(tag, "Generate secret key for user at depth 2");
}
BBGHIBESecretKey SKDepth2 = bbgHIBE.Delegate(SKDepth1, testI2);
//Delegation for depth 3
if (BBGHIBE.isDebug){
Log.i(tag, "Generate secret key for user at depth 3");
}
BBGHIBESecretKey SKDepth3 = bbgHIBE.Delegate(SKDepth2, testI3);
//Delegation for depth 4
if (BBGHIBE.isDebug){
Log.i(tag, "Generate secret key for user at depth 4");
}
BBGHIBESecretKey SKDepth4 = bbgHIBE.Delegate(SKDepth3, testI4);
//Delegation for depth 5
if (BBGHIBE.isDebug){
Log.i(tag, "Generate secret key for user at depth 5");
}
BBGHIBESecretKey SKDepth5 = bbgHIBE.Delegate(SKDepth4, testI5);
//Delegation for depth 6
if (BBGHIBE.isDebug){
Log.i(tag, "Generate secret key for user at depth 6");
}
BBGHIBESecretKey SKDepth6 = bbgHIBE.Delegate(SKDepth5, testI6);
//Delegation for depth 7
if (BBGHIBE.isDebug){
Log.i(tag, "Generate secret key for user at depth 7");
}
BBGHIBESecretKey SKDepth7 = bbgHIBE.Delegate(SKDepth6, testI7);
//encryption
if (BBGHIBE.isDebug){
Log.i(tag, "Encryption");
}
BBGHIBECiphertext ciphertext = bbgHIBE.Encrypt(ciphertextIV);
//Decryption for depth 1
if (BBGHIBE.isDebug){
Log.i(tag, "Dncryption for user at depth 1");
}
bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth1);
//Decryption for depth 2
if (BBGHIBE.isDebug){
Log.i(tag, "Dncryption for user at depth 2");
}
bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth2);
//Decryption for depth 3
if (BBGHIBE.isDebug){
Log.i(tag, "Dncryption for user at depth 3");
}
bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth3);
//Decryption for depth 4
if (BBGHIBE.isDebug){
Log.i(tag, "Dncryption for user at depth 4");
}
bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth4);
//Decryption for depth 5
if (BBGHIBE.isDebug){
Log.i(tag, "Dncryption for user at depth 5");
}
bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth5);
//Decryption for depth 6
if (BBGHIBE.isDebug){
Log.i(tag, "Dncryption for user at depth 6");
}
bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth6);
//Decryption for depth 7
if (BBGHIBE.isDebug){
Log.i(tag, "Dncryption for user at depth 7");
}
bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth7);
}
// public static void main(String[] args){
// testBBEHIBE();
// }
}
Util.java
package cn.edu.buaa.crypto;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;
public class Util {
public static Element hash_id(Pairing pairing, String id){
byte[] byte_identity = id.getBytes();
Element hash = pairing.getZr().newElement().setFromHash(byte_identity, 0, byte_identity.length);
return hash;
}
}
Layout: bbghibe.xml
AndroidManifest.xml
Android屏幕截圖詳解
Android屏幕截圖功能實現這裡介紹兩種方式: 第一種 截取整個屏幕實現方式三種 ImageView imgV = (ImageView) findVie
android圖像圖像處理——自定義組件的屬性
自定義組件的屬性步驟如下【1】在Values資源文件下新建myview.xml 自定義兩個屬性背景圖、畫筆筆觸大小;【2】在
Android開發之PullToRefresh的Click點擊事件的監聽實現長按刪除Item
本文為原創博客,出自http://blog.csdn.net/minimicall 到今天為止,搜芽的賣家版本應該來說已經基本完成,攻堅克難的一路過來。速度也控制的比較好
Android View 事件分發機制源碼詳解(View篇)
前言在Android View 事件分發機制源碼詳解(ViewGroup篇)一文中,主要對ViewGroup#dispatchTouchEvent的源碼做了相應的解析,其