編輯:關於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屏幕截圖功能實現這裡介紹兩種方式: 第一種 截取整個屏幕實現方式三種 ImageView imgV = (ImageView) findVie
自定義組件的屬性步驟如下【1】在Values資源文件下新建myview.xml 自定義兩個屬性背景圖、畫筆筆觸大小;【2】在
本文為原創博客,出自http://blog.csdn.net/minimicall 到今天為止,搜芽的賣家版本應該來說已經基本完成,攻堅克難的一路過來。速度也控制的比較好
前言在Android View 事件分發機制源碼詳解(ViewGroup篇)一文中,主要對ViewGroup#dispatchTouchEvent的源碼做了相應的解析,其