精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

使用BlackBerry Transcoder API集成第三方加密方案

移動開發(fā)
當數(shù)據(jù)從BlackBerry智能手機流向服務器端時也通過AES或者是Triple-DES方式進行加解密操作。也就是說,在BlackBerry平臺上,從BES服務器端到BlackBerry智能手機端都是受平臺的加密保護的。

BlackBerry平臺自身帶有完整的加密機制。所有數(shù)據(jù)從BES(BlackBerry Enterprise Server)流出前都做了加密處理,使用的是AES或者是Triple-DES的方式進行加密。在數(shù)據(jù)到達BlackBerry智能手機后手機端平臺會對數(shù)據(jù)進行解密操作。同樣,當數(shù)據(jù)從BlackBerry智能手機流向服務器端時也通過AES或者是Triple-DES方式進行加解密操作。也就是說,在BlackBerry平臺上,從BES服務器端到BlackBerry智能手機端都是受平臺的加密保護的。

BlackBerry平臺的加密機制

其架構(gòu)如下圖:

 

 

架構(gòu)圖中的紅線部分表示BlackBerry平臺加密的數(shù)據(jù)通道,字符串“Test…”表示明文數(shù)據(jù),而字符串“&^%$...”表示加密后的數(shù)據(jù)。可以看到當數(shù)據(jù)由BES服務器傳向網(wǎng)絡(luò)之前BES服務器會使用管理員指定的AES或者是Triple-DES加密方法對數(shù)據(jù)進行加密。在加密數(shù)據(jù)到達BlackBerry智能手機之前都無法被正常讀取,從而達到保護傳輸數(shù)據(jù)的目的。在BlackBerry智能手機接收到服務器端發(fā)送的數(shù)據(jù)后,首先會根據(jù)管理員指定的解密方法對數(shù)據(jù)進行解密操作,然后將數(shù)據(jù)以明文形式傳遞給手機應用程序。如上所述,當數(shù)據(jù)從BlackBerry智能手機端提交給服務器時BlackBerry會以相類似的過程對數(shù)據(jù)進行加解密操作,從而保證數(shù)據(jù)從手機端提交到服務器端時也受保護。然而,對于很多企業(yè)和組織而言,單純使用廠商提供的密鑰和加密機制是不夠的,他們必須使用自己提供的加密密鑰,或者更進一步,要求使用自身研發(fā)的或者是指定安全提供商研發(fā)的加密機制。在這種情況下就需要在BlackBerry平臺上加入額外的加密機制。如果企業(yè)只是對郵件有額外的加密要求,同時可以接受標準的加密算法,則可以通過S/MIME加密機制的配置形成額外的加密機制。BlackBerry平臺支持S/MIME標準,可以在BES服務器端配置LDAP連接以查找密鑰,然后在BlackBerry智能設(shè)備上引入用戶的密鑰,從而形成完整的加密/簽名機制。在這種配置下,服務器端和BlackBerry智能手機端都可以使用企業(yè)自身提供的加密密鑰。不過,通過S/MIME配置額外的加密機制只作用于郵件,后臺企業(yè)應用通過BES推送到BlackBerry手機端的數(shù)據(jù)是不受二次加密保護的,同樣,BlackBerry智能手機端應用提交到服務器的應用數(shù)據(jù)也是不受二次加密保護的。如果希望對郵件數(shù)據(jù)和應用數(shù)據(jù)都實現(xiàn)二次加密,則需要使用BlackBerry平臺上的Transcoder API。本章節(jié)將詳細介紹Transcoder API,包括Transcoder API的接口和相關(guān)的代碼實現(xiàn)。如果希望了解S/MIME的配置過程,請參考相關(guān)文檔,本章節(jié)不對S/MIME的配置做詳細介紹。

Transcoder API的整體結(jié)構(gòu)

Transcoder API在BlackBerry平臺上提供了二次加密方法,其基本思路是在BES服務器端和BlackBerry智能手機端都預留接口,讓開發(fā)人員可以在服務器端和BlackBerry智能手機端部署加解密應用,從而對所有傳輸?shù)臄?shù)據(jù)進行二次加密。其架構(gòu)示意圖如下:

 

 

示意圖中紅線部分同樣表示BlackBerry平臺加密的數(shù)據(jù),橙線部分表示使用Transcoder加密接口進行加密的數(shù)據(jù)通道,字符串“Test…”表示明文,字符串“Uftu…”表示通過Transcoder加密接口加密過后數(shù)據(jù),字符串“%^$(*…”表示BES加密后的數(shù)據(jù)。可以看到在數(shù)據(jù)離開BES服務器后,它同時受到BlackBerry平臺加密和Transcoder加密接口加密兩層保護,這就形成了數(shù)據(jù)的二次加密。

使用Transcoder API進行二次加密的關(guān)鍵是在服務器和智能手機兩端加入了額外的加解密程序。

服務器端在使用BlackBerry平臺提供的加密方法對數(shù)據(jù)進行加密前會調(diào)用服務器端加解密程序,將所有數(shù)據(jù)提交給服務器端加解密程序。此時服務器端加解密程序的任務就是通過特定的加密算法對傳入的數(shù)據(jù)進行加密,加密后返還給BES服務器。BES服務器在收到服務器端加解密應用所加密的數(shù)據(jù)后,會使用BlackBerry平臺的加密方法對數(shù)據(jù)進行再一次加密,然后才將數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上傳送給智能手機端。

智能手機端在接收到BES服務器傳送的數(shù)據(jù)后,首先使用BlackBerry平臺的解密方法對數(shù)據(jù)進行解密。解密后再調(diào)用手機端加解密應用,將數(shù)據(jù)傳遞給手機端加解密應用。此時的數(shù)據(jù)正是服務器端加解密應用加密過的數(shù)據(jù)。手機端加解密應用需要使用對應的解密算法對數(shù)據(jù)進行解密,最終得到明文,將明文傳遞給手機應用。

從智能手機提交數(shù)據(jù)到BES服務器也通過類似的過程對數(shù)據(jù)進行兩次加解密處理。從以上描述不難發(fā)現(xiàn),在實現(xiàn)二次加密過程服務器端和手機端的加解密程序必須對應,服務器端加解密應用使用某一種加密算法和密鑰,手機端加解密應用必須使用對應的解密算法和密鑰。否則會出現(xiàn)一端無法解密數(shù)據(jù)導致應用處理錯誤的問題。

所以,通過Transcoder API實現(xiàn)二次加密的關(guān)鍵在于如何開發(fā)和部署服務器端和手機端的加解密應用。在下面的章節(jié)中我們會介紹接口的詳細情況和開發(fā)過程。

服務器端Transcoder API介紹

服務器端的Transcoder API是以C/C++頭文件形式提供的,名為:“BES Transcoder API.h”開發(fā)人員需要通過C/C++開發(fā)工具將“BES Transcoder API.h”文件引入項目中,使用c語言對指定方法進行實現(xiàn),最終通過C/C++編譯工具形成一個dll文件。當開發(fā)人員部署所開發(fā)的服務器端加解密應用時需要將所生成的dll文件拷貝到BES服務器上,并通過注冊表“HKEY_LOCAL_MACHINE\SOFTWARE\Research In Motion\BlackBerry Enterprise Server\Dispatcher\Transcoder”指向dll文件所在的位置。

通過這樣的配置,在BES服務器啟動的時候會根據(jù)注冊表找到開發(fā)人員所開發(fā)的dll文件并調(diào)入內(nèi)存。在BES服務器需要對數(shù)據(jù)進行處理時會調(diào)用dll內(nèi)的方法,由開發(fā)人員所實現(xiàn)的加解密方法對數(shù)據(jù)進行處理。

下面詳細描述BES Transcoder API.h為服務器端dll程序定義的函數(shù)

函數(shù):Load DLL()

該函數(shù)在BES服務器加載這個dll時被調(diào)用,開發(fā)人員可以在這個函數(shù)中實現(xiàn)加解密程序所需要的初始化代碼。

函數(shù)定義:int__cdecl Load DLL()

參數(shù):無

返回值:返回0表示加載成功,返回其它值表示加載失敗,該函數(shù)的返回值由開發(fā)人員指定,用于告訴BES服務器本dll是否成功加載了相關(guān)內(nèi)容。

函數(shù):Free DLL()

該函數(shù)在BES服務器釋放該dll時被調(diào)用,開發(fā)人員可以在這個函數(shù)中加入對象釋放等資源回收代碼。

函數(shù)定義:void Free DLL()

參數(shù):無

返回值:無

函數(shù):Get ID()

該函數(shù)用于返回服務器端加解密應用程序的ID,這個函數(shù)的返回值作為該應用的標記,所以它必須和客戶端的對應getID方法返回相同的值,讓BlackBerry平臺可以找到對應的解密應用。

函數(shù)定義:unsignedchar__cdecl GetId()

參數(shù):無

返回值:返回一個unsignedchar類型的值,不能為0,開發(fā)人員可以根據(jù)約定任意指定一個非0的unsignedchar值,前提就是服務器端返回的ID值和客戶端返回的ID值相同。

函數(shù):Will Transcode()

該函數(shù)讓dll決定是否對相應的內(nèi)容進行加解密處理。函數(shù)定義:int__cdecl Will Transcode(const Transcoder Context*constcontext)

參數(shù):context用于獲取傳入的內(nèi)容的上下文,從而判斷是否需要對其進行加密。返回值:當該函數(shù)返回0時表明需要對內(nèi)容進行加解密處理,返回其它非0值則表明不需要對內(nèi)容進行加解密處理。值-1為保留字TRANSCODE_ERROR,在這里不能作為返回值使用。

函數(shù):Encode()

該函數(shù)用于對數(shù)據(jù)進行加密,BES服務器在發(fā)送數(shù)據(jù)前會調(diào)用這個方法,開發(fā)人員需要在這個函數(shù)中實現(xiàn)加密算法。

函數(shù)定義:int__cdecl Encode(Transcoder Input Stream*constinput,Transcoder Output Stream*constoutput,const Transcoder Context*constcontext)

參數(shù):

input為BES服務器傳入的內(nèi)容,開發(fā)人員可以從中讀取消息內(nèi)容output為傳給BES服務器的內(nèi)容,開發(fā)人員需要將加密過的數(shù)據(jù)寫入該參數(shù)中context消息上下文,用于獲取消息內(nèi)容主體以外的其它相關(guān)信息。返回值:當該函數(shù)返回0時表明加密成功,返回其它非0值則表明加密不成功。注意,如果該函數(shù)返回非0值則傳入的內(nèi)容會被丟失。值-1為保留字TRANSCODE_ERROR,在這里不能作為返回值使用。

函數(shù):Decode()

該函數(shù)用于對數(shù)據(jù)進行解密,BES服務器在接收到數(shù)據(jù)后會調(diào)用這個方法,開發(fā)人員需要在這個函數(shù)中實現(xiàn)解密算法。

函數(shù)定義:int__cdecl Decode(Transcoder Input Stream*constinput,Transcoder Output Stream*constoutput,const Transcoder Context*constcontext)

參數(shù):input為BES服務器傳入的內(nèi)容,開發(fā)人員可以從中讀取消息內(nèi)容output為傳給BES服務器的內(nèi)容,開發(fā)人員需要將解密過的數(shù)據(jù)寫入該參數(shù)中context消息上下文,用于獲取消息內(nèi)容主體以外的其它相關(guān)信息。返回值:當該函數(shù)返回0時表明解密成功,返回其它非0值則表明解密不成功。注意,如果該函數(shù)返回非0值則傳入的內(nèi)容會被丟失。值-1為保留字TRANSCODE_ERROR,在這里不能作為返回值使用。

手機端Transcoder API介紹

手機端Transcoder API以Java類的形式提供,主要的類名為“net.rim.device.api.crypto.transcoder.Transcoder”。開發(fā)人員需要繼續(xù)這個類,并實現(xiàn)其中指定的方法。另外,為了讓開發(fā)人員所開發(fā)的類生效,需要調(diào)用“net.rim.device.api.crypto.transcoder.TranscoderManager”類的register方法注冊所開發(fā)的Transcoder子類。最后,開發(fā)人員通BlackBerry開發(fā)工具生成一個可以在BlackBerry智能手機上運行的程序。因為手機端的加解密程序需要對所有數(shù)據(jù)進行處理,一般這個應用會設(shè)置為自啟動的應用。在部署手機端加解密應用的時候,需要將所生成的手機應用安裝到手機設(shè)備上。如果該程序被設(shè)置為自啟動應用,BlackBerry智能手機會自動將該程序載入內(nèi)存。當需要對數(shù)據(jù)進行處理的時候,會調(diào)用該程序特定的方法,由該方法對數(shù)據(jù)進行處理。

繼承法Transcoder類后所需要實現(xiàn)的函數(shù)有:

函數(shù):get ID()

用于獲取客戶端應用的ID,開發(fā)人員可以在該函數(shù)中返回0以外的任意byte類型的值,前提是返回值必須和服務器端應用GetID函數(shù)的返回值相同。

函數(shù)定義:publicfinalbyteget ID()

參數(shù):無

返回值:該方法返回一個byte類型的值作為客戶端應用的ID,如上所述,這里返回的ID必須和服務器端應用GetID方法返回的值相同。

函數(shù):will Transcode()

該函數(shù)讓開發(fā)人員判斷是否需要對傳入的內(nèi)容進行加解密處理。它的作用主要是過濾那些不需要加解密操作的消息。

函數(shù)定義:publicbooleanwillTranscode(IntHashtablecontext)

參數(shù):context用于獲取傳入的內(nèi)容的上下文,從而判斷是否需要對其進行加密。返回值:返回true表示需要對內(nèi)容進行加解密處理,返回false表示不需要對內(nèi)容進行加解密處理。

函數(shù):encode()

該函數(shù)用于對數(shù)據(jù)進行加密,BlackBerry智能手機在發(fā)送數(shù)據(jù)前會調(diào)用這個方法,開發(fā)人員需要在這個函數(shù)中實現(xiàn)加密算法。

函數(shù)定義:publicbooleanencode(Input Streaminput,Output Streamoutput,Int Hashtablecontext)

參數(shù):input為BlackBerry智能手機傳入的內(nèi)容,開發(fā)人員可以從中讀取消息內(nèi)容output為BlackBerry智能手機的內(nèi)容,開發(fā)人員需要將加密過的數(shù)據(jù)寫入該參數(shù)中context消息上下文,用于獲取消息內(nèi)容主體以外的其它相關(guān)信息。返回值:當該函數(shù)返回true時表明加密成功,返回false則表明加密不成功。注意,如果該函數(shù)返回非0值則傳入的內(nèi)容會被丟失。值-1為保留字TRANSCODE_ERROR,在這里不能作為返回值使用。

函數(shù):decode()

該函數(shù)用于對數(shù)據(jù)進行解密,BlackBerry智能手機在接收到數(shù)據(jù)后會調(diào)用這個方法,開發(fā)人員需要在這個函數(shù)中實現(xiàn)解密算法。

函數(shù)定義:publicbooleandecode(Input Streaminput,Output Streamoutput,Int Hashtablecontext)

參數(shù):input為BlackBerry智能手機傳入的內(nèi)容,開發(fā)人員可以從中讀取消息內(nèi)容output為傳給BlackBerry智能手機的內(nèi)容,開發(fā)人員需要將解密過的數(shù)據(jù)寫入該參數(shù)中context消息上下文,用于獲取消息內(nèi)容主體以外的其它相關(guān)信息。返回值:當該函數(shù)返回true時表明解密成功,返回false則表明多彩密不成功。#p#

創(chuàng)建服務器端程序

如以前文所述,服務器端的加解密程序是以dll形式部署的,所以,要開發(fā)服務器端加解密程序需要一個可以將c語言代碼編譯成dll的工具。為了方便,本例使用Visual C++ 6.0作為開發(fā)工具,讀者可以根據(jù)自己的習慣選用其它類似工具。

啟動Visual C++ 6.0,點擊“File->New”以創(chuàng)建一個新的項目,如下圖:

 

 

點擊“File->New”菜單后系統(tǒng)會彈出新建向?qū)Вx擇“Projects”標簽頁以創(chuàng)建項目。在“Project”標簽頁中選擇“Win32 Dynamic-Link Library”以創(chuàng)建一般的Win32 dll。在“Project Name”一欄中輸入項目名,本例為“My Transcoder”,同時指定項目所在的文件目錄,本例使用“c:\workspace\vc6\My Transcoder”作為項目所在的文件目錄。保持其它選項,點擊“OK”,系統(tǒng)將創(chuàng)建一個名為My Transcoder的項目,同時創(chuàng)建對應的workspace。示意圖如下:

 

 

在項目創(chuàng)建過程中向?qū)崾拘枰獎?chuàng)建什么類型的dll項目,為了代碼編寫方便,我們選擇“Asimple Dllproject”,就是創(chuàng)建一個簡單的dll項目,由系統(tǒng)生成一些基本的文件。選擇后點擊“Finish”

 

 

向?qū)ЫY(jié)束后系統(tǒng)會出現(xiàn)提示框以確認項目的細節(jié),點擊“OK”關(guān)閉這個確認框。

 

 

My Transcoder項目創(chuàng)建以后可以發(fā)現(xiàn)項目中有一些系統(tǒng)生成的文件,包括Std Afx.h,Std Afx.cpp和My Transcoder.cpp。我們需要編輯的是My Transcoder.cpp,在這里完成Transcoder API的實現(xiàn)。雙擊左邊導航條中的“My Transcoder.cpp”文件以打開該文件,可以看到系統(tǒng)生成了Dll Main方法,這個方法是dll的入口方法,所以系統(tǒng)自動生成了該方法。如下圖:

 

 

因為我們在項目中要使用Transcoder API,所以下一步工作就是將Transcoder API提供的頭文件“BES Transcoder API.h”引入到項目中。“BES Transcoder API.h”文件隨文檔提供,讀者也可以在BlackBerry官方網(wǎng)站上下載。獲取到“BES Transcoder API.h”文件后,在操作系統(tǒng)上將這個文件拷貝到項目目錄中,本例就是“C:\workspace\vc6\My Transcoder”目錄。然后,在Visual C++ 6.0界面中左邊導航條中選擇“Header Files”,點擊右鍵,選擇“Add Filesto Folder…”,然后選擇剛拷貝的“BES Transcoder API.h”,這樣就可以將頭文件“BES Transcoder API.h”引入到當前項目中。

 

 

引入頭文件“BES Transcoder API.h”后結(jié)果如下圖,有興趣的讀者可以雙擊該文件打開它,了解一下頭文件“BES Transcoder API.h”中所定義的方法。

 

 

引入頭文件“BES Transcoder API.h”后,在左邊導航條中雙擊“My Transcoder.cpp”文件,編輯My Transcoder.cpp文件,使該文件的內(nèi)容和似下代碼相同。讀者為了方便,可以將系統(tǒng)生成的代碼行刪除,直接將以下代碼粘貼到My Transcoder.cpp文件中:

  1. // My T r ans c o de r .c pp : De fin es t he en t ry po in t f o r t he DL L app li ca t io n.  
  2.  
  3. #in cl ud e " s t da fx.h "  
  4.  
  5. #in cl ud e " BE S T r ans c o der AP I. h"  
  6.  
  7. #in cl ud e   
  8.  
  9. F ILE * logF il e;  
  10.  
  11. ch ar LogF il eN am e[ 6 4 ]="c :\\ T r ans c o der \\ T r ans c o de r -Log . t xt" ;  
  12.  
  13. DEF INE_ BE S _T RA NSC OD E R_ DLL  
  14.  
  15. BOO L AP IE NTR Y Dll Ma in ( HA NDLE h Mo du le,  
  16.  
  17. DW ORD ul _ r easo n_f o r _c al l, LP V OI D lp R ese r v ed  
  18.  
  19. )  
  20.  
  21. {  
  22.  
  23. prin t f( " Lo ad in g Dl l" ) ;  
  24.  
  25. r et urn T RU E ;  
  26.  
  27. }  
  28.  
  29. __ decls pec ( dl l e xpo rt )  
  30.  
  31. in t __cdec l Lo ad D LL( )  
  32.  
  33. {  
  34.  
  35. logF il e = f o pen( Log Fil eN am e , "a" ) ;  
  36.  
  37. fprin t f( logF il e,"t ryin g t o c al l Lo ad Dl l" ) ;  
  38.  
  39. r et urn 0 ;  
  40.  
  41. }  
  42.  
  43. __ decls pec ( dl l e xpo rt )  
  44.  
  45. v o id __cd ecl F r ee DL L( )  
  46.  
  47. {  
  48.  
  49. fprin t f( logF il e,"Dl l fre e") ;  
  50.  
  51. }  
  52.  
  53. __ decls pec ( dl l e xpo rt )  
  54.  
  55. uns ig ned c ha r __ cd ecl G et ID ( )  
  56.  
  57. {  
  58.  
  59. uns ig ned lo ng T r ans c o de rID =2 0 ;  
  60.  
  61. fprin t f( logF il e,"t ryin g t o g et I D" ) ;  
  62.  
  63. r et urn ( uns ig ned c ha r ) T r ans c o de rID ;  
  64.  
  65. }  
  66.  
  67. __ decls pec ( dl l e xpo rt )  
  68.  
  69. in t __cdec l W il l T r ans c o de( c o ns t T r ans c o derCo n t e xt *c o ns t c o n t e xt )  
  70.  
  71. {  
  72.  
  73. r et urn 0 ;  
  74.  
  75. }  
  76.  
  77. __ decls pec ( dl l e xpo rt )  
  78.  
  79. in t __cdec l En c o de ( T r ans co derIn putSt r eam *c o ns t in put , T r a ns c o derOut putSt r eam *c o ns t o ut put , c o ns t T r ans co der Co n t e xt *c o ns t c o n t e xt )  
  80.  
  81. {  
  82.  
  83. fprin t f( logF il e,"t es t in g enc o de is r un ni ng no w") ;  
  84.  
  85. uns ig ned c ha r r ead C;  
  86.  
  87. fprin t f( logF il e," /n enc o de r ead ch ar : " ) ;  
  88.  
  89. whi le ( in put - >R ead ( & r ead C) )  
  90.  
  91. {  
  92.  
  93. fprin t f( logF il e,"%c" ,r ea dC) ;  
  94.  
  95. o ut put ->W rit e( r eadC ) ;  
  96.  
  97. }  
  98.  
  99. r et urn 0 ;  
  100.  
  101. }  
  102.  
  103. __ decls pec ( dl l e xpo rt )  
  104.  
  105. in t __cdec l D ec o de( T r ans c o derIn putSt r eam *c o ns t in put , T r a ns c o derOut putSt r eam *c o ns t o ut put , c o ns t T r ans c o der Co n t e xt *c o ns t c o n t e xt )  
  106.  
  107. {  
  108.  
  109. fprin t f( logF il e," /n dec o de r ead c ha r : " ) ;  
  110.  
  111. uns ig ned c ha r r ead C;  
  112.  
  113. whi le ( in put - >R ead ( & r ead C) )  
  114.  
  115. {  
  116.  
  117. fprin t f( logF il e,"%c" ,r ea dC) ;  
  118.  
  119. o ut put ->W rit e( r eadC ) ;  
  120.  
  121. }  
  122.  
  123. r et urn 0 ;  
  124.  
  125. }  

編輯代碼后結(jié)果如下圖:

 

 

最后,點擊“Build->Build My Transcoder.dll”菜單生成dll文件。使用Visual C++ 6.0的標準設(shè)置的話,所生成的dll文件可以在項目的Debug目錄中找到,本例就是C:\workspace\vc6\My Transcoder\Debug目錄。

 

 

如果在編譯過程中出現(xiàn)錯誤的話請根據(jù)控制臺的錯誤提示對代碼進行修改并重新編譯。編譯成功后你就完成了服務器加解密應用的生成工作了,在后面的章節(jié)中會對代碼進行詳細解釋。這里提醒讀者的是本例使用的樣例代碼是一個“空”的加解密代碼,在加解密過程中只是單純地將輸入的數(shù)據(jù)傳到輸出接口,在現(xiàn)實環(huán)境中使用的話開發(fā)人員的進一步工作就是修改樣例代碼中的Encode和Decode,使其可以對數(shù)據(jù)進行真正的加密和解密工作。#p#

創(chuàng)建客戶端程序

Transcoder API客戶端是以BlackBerry應用形式存在于智能手機的,所以,要創(chuàng)建客戶端的加解密應用,需要使用BlackBerry開發(fā)環(huán)境開發(fā)一個BlackBerry應用程序。

本例使用BlackBerry JDE Plug-In For Eclipse 1.1開發(fā)環(huán)境創(chuàng)建了一個名為Transcoder Client的BlackBerry項目。有關(guān)BlackBerry項目的創(chuàng)建過程以及BlackBerry JDE Plug-In For Eclipse的具體使用,請參考相關(guān)文檔,本文只描述Transcoder Client項目創(chuàng)建過程中的關(guān)鍵步驟,不對項目創(chuàng)建的每一個過程進行描述。

創(chuàng)建BlackBerry項目后,創(chuàng)建一個Java包以包含將要創(chuàng)建的Java類,本例使用

“org.bbtesting.transcoder”作為包名。然后在該包中創(chuàng)建Transcoder API客戶端的入口程序,名為Main App。

注意,一般而言Transcoder API客戶端加解密應用會以自啟動方式啟動,不需要用戶干預,本例考慮到測試的便利性,通過應用程序圖標的方式啟動應用,然后通過菜單啟動客戶端加解密線程。

在Main App類文件中對代碼進行修改,使其如以下代碼:

  1. package org.damon.transcoder;  
  2.  
  3. import net.rim.device.api.ui.UiApplication;  
  4.  
  5. import net.rim.device.api.ui.container.MainScreen;  
  6.  
  7. public class MainApp extends UiApplication {  
  8.  
  9. public static void main(String[] args) { MainApp _app = new MainApp();  
  10.  
  11. _app.enterEventDispatcher();  
  12.  
  13. }  
  14.  
  15. public MainApp() {  
  16.  
  17. MainScreen screen = new MyScreen( );  
  18.  
  19. this .pushScreen(screen);  
  20.  
  21. }  
  22.  
  23. }  

如果讀者仔細閱讀Main App中的方法,可以發(fā)現(xiàn)該類主要是創(chuàng)建了應用程序入口,在程序入口中創(chuàng)建了My Screen類的實例,并將該實例顯示出來。所以,下一步的工作就是要創(chuàng)建My Screen類,讀者在按以下步驟創(chuàng)建My Screen類之前編譯本項目的話會出現(xiàn)找不到類My Screen的錯誤。

在包org.bbtesting.transcoder中創(chuàng)建類My Screen,創(chuàng)建過程中選擇繼承類Main Screen,然后編輯My Screen類,使其如以下代碼:

  1. package org.bbtest .transcoder;  
  2.  
  3. import net.rim.device.api.crypto.transcoder.TranscoderManager;  
  4.  
  5. import net.rim.device.api.ui.MenuItem;  
  6.  
  7. import net.rim.device.api.ui.UiApplication;  
  8.  
  9. import net.rim.device.api.ui.component.EditField;  
  10.  
  11. import net.rim.device.api.ui.container.MainScreen;  
  12.  
  13. public class MyScreen extends MainScreen {  
  14.  
  15. private MenuItem start = new MenuItem( "start" , 200000, 10) {  
  16.  
  17. public void run() {  
  18.  
  19. register();  
  20.  
  21. }  
  22.  
  23. };  
  24.  
  25. private EditField logField = new EditField();  
  26.  
  27. public MyScreen() {  
  28.  
  29. this .addMenuItem( start ); logField .setText( "Transcoder Testing client" ); this .add( logField );  
  30.  
  31. }  
  32.  
  33. private void register() { this .log( "start to register" ); try {  
  34.  
  35. MyTranscoder transcoder = new MyTranscoder(); transcoder.SetScreen( this ); TranscoderManager .register (transcoder);  
  36.  
  37. } catch (Exception e) {  
  38.  
  39. System. out .println( "Exception while registering:" + e);  
  40.  
  41. this .log( "Exception while registering:" + e);  
  42.  
  43. }  
  44.  
  45. }  
  46.  
  47. public void log( final String msg) {  
  48.  
  49. UiApplication. getUiApplication ().invokeLater( new Runnable() {  
  50.  
  51. public void run() {  
  52.  
  53. logField .setText( logField .getText() + "\n" + msg); System. out .println(msg);  
  54.  
  55. }  
  56.  
  57. });  
  58.  
  59. }  
  60.  
  61. }  

在以上的My Screen類中主要是創(chuàng)建一個屏幕,在該屏幕上添加一個菜單項,用戶可以點擊這個菜單項啟動客戶端加解密應用。啟動的過程就是將一個My Transcoder類傳遞給系統(tǒng),讓系統(tǒng)在處理所有數(shù)據(jù)的時候都調(diào)用這個My Transcoder類。

因為我們在本項目中還沒有創(chuàng)建My Transcoder類,此時編譯項目會出現(xiàn)找不到My Transcoder類的錯誤。下面的工作就是要創(chuàng)建My Transcoder類,這也是創(chuàng)建Transcoder客戶端加解密應用的最關(guān)鍵步驟。

在包org.bbtest.transcoder中創(chuàng)建名為My Transcoder的類,創(chuàng)建過程中選擇繼承類net.rim.device.api.crypto.transcoder.Transcoder。創(chuàng)建該類后修改其代碼,結(jié)果如下:

  1. package org.bbtest .transcoder;  
  2.  
  3. import java.io.InputStream;  
  4.  
  5. import java.io.OutputStream;  
  6.  
  7. import net.rim.device.api.crypto.transcoder.Transcoder;  
  8.  
  9. import net.rim.device.api.util.IntHashtable;  
  10.  
  11. public class MyTranscoder extends Tran scoder {  
  12.  
  13. private MyScreen screen = null ;  
  14.  
  15. public MyTranscoder() {  
  16.  
  17. super (( byte ) 20);  
  18.  
  19. }  
  20.  
  21. public void SetScreen(MyScreen screen) {  
  22.  
  23. this . screenscreen = screen;  
  24.  
  25. }  
  26.  
  27. public boolean decode(InputStream input, OutputStream output, IntHashtable context) {  
  28.  
  29. this . screen .log( "decodeing" );  
  30.  
  31. try {  
  32.  
  33. int readByte = input.read();  
  34.  
  35. while (readByte != -1) { output.write(readByte); readByte = input.read();  
  36.  
  37. }  
  38.  
  39. output.flush();  
  40.  
  41. } catch (Exception e) { this . screen .log( "Exception in decode:" + e); return false ;  
  42.  
  43. }  
  44.  
  45. return true ;  
  46.  
  47. }  
  48.  
  49. public boolean encode(InputStream input, OutputStream output,  
  50.  
  51. IntHashtable context) {  
  52.  
  53. this . screen .log( "encodeing" );  
  54.  
  55. try {  
  56.  
  57. int readByte = input.read();  
  58.  
  59. while (readByte != -1) { output.write(readByte); readByte = input.read();  
  60.  
  61. }  
  62.  
  63. output.flush();  
  64.  
  65. } catch (Exception e) { this . screen .log( "Exception in decode:" + e); return false ;  
  66.  
  67. }  
  68.  
  69. return true ;  
  70.  
  71. }  
  72.  
  73. public boolean willTranscode(IntHashtable context) {  
  74.  
  75. return true ;  
  76.  
  77. }  
  78.  
  79. }  

完成代碼輸入后嘗試編譯該項目,如果讀者使用缺省的“自動編譯”的設(shè)置,則在保存代碼的時候開發(fā)環(huán)境會自動進行編譯。在編譯過程中出現(xiàn)錯誤的話按系統(tǒng)提示對錯誤進行修改。最終形成的cod文件就可以用于部署了。

加載客戶端程序

在完成應用創(chuàng)建過程后,就要開始加載客戶端的程序了。在這里要注意的是成功部署客戶端加解密應用后,該應用將作用于這個用戶的所有數(shù)據(jù),如果服務器商地面有沒有部署對應加解密應用,用戶將會無法接收數(shù)據(jù),同時也無法向服務器發(fā)送數(shù)據(jù)。所以在測試的時候要考慮到其它測試用戶,在生產(chǎn)環(huán)境中部署的過程中更是要注意配置過程對生產(chǎn)用戶的影響。本例只說明測試環(huán)境中的配置過程,所以不考慮生產(chǎn)環(huán)境配置過程的統(tǒng)籌安排。為了加載客戶端程序,首先要做的是對客戶端程序進行簽名,因為客戶端加解密程序使用到了受控制的API,沒有簽名的話將無法運行。有關(guān)客戶端應用的簽名密鑰的申請和簽名工具的使用請參考相關(guān)文檔。

對客戶端程序進行簽名后,可以通過Java loader將客戶端程序的cod文件直接通過USB連線安裝到BlackBerry智能手機上。當然讀者也可以選擇自己熟悉的方式,如OTA方式或者是BlackBerry Desktop Manager的方式將應用安裝到BlackBerry智能手機上。安裝完該應用后如果讀者嘗試在BlackBerry智能手機上運行該程序的話,會發(fā)現(xiàn)該應用程序仍無法正常工作。其原因是BlackBerry平臺對于Transcoder的使用控制比較嚴格,必須在BES服務器上做相應設(shè)置才可以在客戶端運行Transcoder API相關(guān)的應用。

要在客戶端運行Transcoder API相關(guān)的應用,必須在BES服務器上為該用戶創(chuàng)建一個IT Policy,并在IT Policy中指定客戶端程序的hash碼。

獲取cod文件的hash碼有多種方式,如果是自己開發(fā)的cod應用,可以在開發(fā)環(huán)境生成的對應的jad文件中得到該cod應用的hash碼,下面是Transcoder Client.cod對應的jad文件Transcoder Client.jad的內(nèi)容,其中第9行的RIM-COD-SHA1的內(nèi)容就是該cod文件的has碼,使用時注意將中間的空格刪除,本例中得到的結(jié)果是:

0 1 f 25 24 f 0 0 f a 5 9 0 89 6 05 2 556 b6f 7 f 1 55 4 5 0 27 e 5 2 。

 

 

如果是他人開發(fā)的cod應用,有時并沒有附帶提供對應的jad文件。這時可以通過命令Java loader得到一個cod文件對應的hash碼。Java loader命令的格式如下:Java loader siblinginfo

本例中為了更好地顯示Java loader命令的輸出,在命令行界面執(zhí)行以下命令將輸出的結(jié)果寫入文件c:\temp\codinfo.txt中:Java loader siblinginfo Transcoder Client.cod>c:\temp\codinfo.txt

得到的codinfo.txt打開以后如下圖:

 

 

其中Hash一欄顯示的就是Transcoder Client.cod對應的hash碼。

獲取cod的hash碼以后需要將該hash碼配置到IT Policy中,編輯所創(chuàng)建的IT Policy,選擇“Security”標簽頁,下圖是在BES5.0Web管理界面中得到的載圖:

 

 

在選擇“Security”簽標頁后,滾動頁面,找到“Security Transcoder Cod File Hashes”一欄,將上面找到的hash碼填入,如下圖:

 

 

完成后保存該IT Policy,為測試用戶分配該IT Policy,并向測試用戶推送一次IT Policy,以保證該IT Policy作用于該測試用戶。

在完成IT Policy配置后,所安裝的Transcoder Client應用就可以正常運行了,運行該應用后,可以選擇菜單中的“Start”菜單項啟動客戶端加解密應用。

在啟動客戶端加解密應用后,會發(fā)現(xiàn)該BlackBerry智能手機無法正常收發(fā)郵件,這是因為服務器端沒有部署對應的加解密程序。只有在服務器端也部署對應的加解密程序后整個Transcoder應用才能正常工作,下面將描述服務器端應用的部署過程。

配置服務器端程序

如之前描述的,Transcoder服務器端程序是通過BES服務器上的注冊表配置的。要配置服務器Transcoder程序,需要訪問BES服務器,將我們創(chuàng)建的服務器端程序,也就是生成的My Transcoder.dll拷貝到BES服務器上,本例將My Transcoder.dll拷貝在BES服務器的“c:\workspace\transcoder”目錄下。

然后,在BES服務器所在的Windows操作系統(tǒng)下運行“regedit”啟動注冊表編輯器。在注冊表編輯器中找到以下配置:“HKEY_LOCAL_MACHINE\SOFTWARE\Research In Motion\BlackBerry Enterprise Server\Dispatcher”。在初始狀態(tài)下,“Dispatcher”配置中不會出面“Transcoder”子項目,此時需要對“Dispatcher”項點擊右鍵,選擇“新建->項”,在新建項對話框中輸入項目名為“Transcoder”。完成“Transcoder”項創(chuàng)建后,雙擊“Transcoder”項打開該項,并點擊右鍵,選擇“新建->字符串值”,在新建字符串值對話框中,在名稱一欄輸入“Transcoder”,在數(shù)據(jù)一欄輸入服務器端應用dll文件的全路徑名稱,本例中為

“c:\workspace\transcoder\My Transcoder.dll”。配置后的結(jié)果如下圖:

 

 

完成該配置之后需要重啟BES服務器的Dispatcher任務才能讓所配置的dll調(diào)入內(nèi)存,重啟的時候可以通過Windows的服務管理器重啟,也可以通過BES管理界面重啟整個BES服務器。注意,因為在本例中的My Transcoder.dll在載入時會嘗試在目錄“c:\transcoder”目錄下生成日志文件,所以讀者如果使用本例的My Transcoder.dll,在重新啟動BES服務器之前需要手工創(chuàng)建目錄:“c:\transcoder”,以避免程序出現(xiàn)錯誤導致BES服務器無法啟動。下圖為BES5.0Web管理界面中重啟BES服務器的方法:

 

 

在服務器重啟過程中注意觀察BES服務器的Dispatcher的日志,該日志在BES服務器安裝日錄的Logs目錄下,本例在“C:\Program Files\Research In Motion\BlackBerry Enterprise Server\Logs”目錄中。在缺省配置下,Dispatcher任務的日志以“APP_DISP”開頭,如:“APP_DISP_01_20100202_0001.txt”。

如果服務器端應用加載成功的話,可以在Dispatcher日志中發(fā)現(xiàn)“Transcoder DLL loaded”一句,如下圖:

 

 

如果無法加載的話也會有對應的錯誤,出現(xiàn)無法加載錯誤的話有可能是注冊表中輸入的dll路徑不對,需要檢查Transcoder項的內(nèi)容。如果在Dispatcher日志中根本沒有發(fā)現(xiàn)transcoder相關(guān)的日志,則說明注冊表配置沒有生效,有可能注冊表項的名稱或者是位置不對,需要檢查注冊表中的Transcoder項是不是在正確位置。

測試結(jié)果

對應用進行測試會發(fā)現(xiàn),如果客戶端和服務器端都正確部署了Transcoder加密解應用,智能手機可以正常收發(fā)郵件。因為本例中的Transcoder加密解應用是一個“空”的加解密應用,并沒有對數(shù)據(jù)進行加解密操作,所以在測試過程中的表現(xiàn)和沒有部署Transcoder加密解應用的情況相同。不過,讀者可以從Transcoder日志(本例為c:\transcoder\Transcoder-Log.txt)中看到所有服務器和客戶端交互的數(shù)據(jù)都被Transcoder加密解應用載獲了。

代碼分析

服務器端代碼分析

為了讓讀者更好地了解Transcoder API的使用,下面對服務器端代碼進行分析。

#include"stdafx.h"

#include"BEST ranscoder API.h"

#include以上代碼為頭文件引入代碼,主要是要引入名為“BESTranscoder API.h”,該頭文件內(nèi)定義了Transcoder API使用所需要的函數(shù)與常量等關(guān)鍵元素。

  1. FILE*logFile; 

charLogFileName[64]="c:\\Transcoder\\Transcoder-Log.txt";以上代碼為日志文件句柄與日志文件名的定義,日志操作在Transcoder API的使用中并不是必要的,本例為了讓應用執(zhí)行有更加明顯的,可以跟蹤的結(jié)果,所以通過日志文件記錄相關(guān)信息。本例中的日志文件名硬編碼為“c:\\Transcoder\\Transcoder-Log.txt”,讀者可以根據(jù)測試環(huán)境的情況進行修改,注意要調(diào)整變量LogFileName數(shù)組的上界。

  1. DEFINE_BES_TRANSCODER_DLL 

以上這句為Transcoder API定義語句的引入,這句是Transcoder API使用的關(guān)鍵,為了讓頭文件“BESTranscoder API.h”中的相關(guān)定義可以在本程序中使用,必須通過語句DEFINE_BES_TRANSCODER_DLL將預定義好的相關(guān)元素引入。對c/c++中的預定義機制有疑惑的讀者可以閱讀相關(guān)文檔以了解這句語句的含義,當然,也可以不深究這句語句的語法,只記住在Transcoder API使用時必須有這句語句也可以。

  1.  
  2.  
  3. BOO L AP IE NTR Y Dll Ma in ( HA NDLE h Mo du le, DWO RD ul_ r easo n_f o r _c al l, LP V OI D lp R e s er v ed )  
  4.  
  5. {  
  6.  
  7. prin t f( " Lo ad in g Dl l" ) ;  
  8.  
  9. r et urn T RU E ;  
  10.  
  11. }  

以上為本dll應用的入口,按dll的載入機制,這個函數(shù)在服務器載入該dll時被調(diào)用。本例只是在標準輸出中輸出了“LoadingDll”,并沒有執(zhí)行其它操作。

  1. __ decls pec ( dl l e xpo rt )  
  2.  
  3. in t __cdec l Lo ad D LL( )  
  4.  
  5. {  
  6.  
  7. logF il e = f o pen( LogF il eN am e , "a" ) ; fprin t f( logF il e,"t ryin g t o c al l Lo ad Dl l" ) ; r et urn 0 ;  
  8.  
  9. }  

以上代碼為dll載入代碼,適合加入一些只需要在載入過程中運行一次的代碼,如本例中日志文件的打開只需要在dll載入時運行一次,所以在這里加入日志文件打開的語句fopen。此外,本例的該函數(shù)還在日志文件中記錄了“tryingtocallLoadDll”字符串。在實際環(huán)境中這里可以加入加解密應用初始化的代碼,比如在這里可以加入連接CA獲取服務器密鑰的代碼。此函數(shù)返回0,表示加載成功,實際環(huán)境中此處可以根據(jù)初始化代碼的運行情況決定返回什么值,如果初始化失敗,則可以返回其它非0值。注意,如果返回其它非0值,該dll將不會被載入內(nèi)存,相關(guān)的加解密方法也不會被調(diào)用。

  1. __ decls pec ( dl l e xpo rt )  
  2.  
  3. v o id __cd ecl F r ee DL L( )  
  4.  
  5. {  
  6.  
  7. fprin t f( logF il e,"Dl l fre e") ;  
  8.  
  9. }  

Free Dll函數(shù)為dll釋放函數(shù),可以加入連接關(guān)閉等資源釋放代碼。本例不需要釋放資源,所以在該函數(shù)中只是通過日志文件記錄了字符串“Dll free”。

  1. __ decls pec ( dl l e xpo rt )  
  2.  
  3. uns ig ned c ha r __ cd ecl G et ID ( )  
  4.  
  5. {  
  6.  
  7. uns ig ned lo ng T r ans c o de rID =2 0 ; fprin t f( logF il e,"t ryin g t o g et I D" ) ; r et urn ( uns ig ned c ha r ) T r ans c o de rID ;  
  8.  
  9. }  

Get ID函數(shù)需要返回本應用的ID,本例使用20作為應用ID,所以返回20。注意要確定返回的值是unsignedchar類型。

  1. __ decls pec ( dl l e xpo rt )  
  2.  
  3. in t __cdec l W il l T r ans c o de( c o ns t T r ans c o derCo n t e xt *c o ns t c o n t e xt )  
  4.  
  5. {  
  6.  
  7. r et urn 0 ;  
  8.  
  9. }  

Will Transcode用于確定是否需要對消息進行加解密操作,返回非零值表示不需要進行加解密操作,本例對所有消息都返回0,表示對所有消息都需要進行加解密操作。

  1.  
  2.  
  3. __ decls pec ( dl l e xpo rt )  
  4.  
  5. in t __cdec l En c o de ( T r ans co derIn putSt r eam *c o ns t in put , T r a ns c o derOut putSt r eam *c o ns t o ut put , c o ns t T r ans co der Co n t e xt *c o ns t c o n t e xt )  
  6.  
  7. {  

函數(shù)Encode用于對消息進行加密操作,注意參數(shù)有input,output,context,其中input為系統(tǒng)傳入的輸入流,output為傳給系統(tǒng)的輸出流,本函數(shù)的主要工作就是從input中獲取數(shù)據(jù),進行加密操作,然后通過output傳送給系統(tǒng)。

  1. fprin t f( logF il e,"t es t in g enc o de is r un ni ng no w") ; 

以上代碼在日志文件中輸出“testingencodeisrunningnow”,用于記錄Encode事件。

  1. uns ig ned c ha r r ead C;  
  2.  
  3. fprin t f( logF il e," /n enc o de r ead c ha r : " ) ;  
  4.  
  5. whi le ( in put - >R ead ( & r ead C) )  
  6.  
  7. {  
  8.  
  9. fprin t f( logF il e,"%c" ,r ea dC) ;  
  10.  
  11. o ut put ->W rit e( r eadC ) ;  
  12.  
  13. }  

以上代碼定義了變量readC,調(diào)用input的Read方法將數(shù)據(jù)讀到變量readC中,然后將read C輸出到日志文件中進行記錄,同時調(diào)用output的Write方法將readC中的數(shù)據(jù)寫入到output輸出流中。通過不斷的循環(huán)可以將input中的所有數(shù)據(jù)傳送到output中。本段代碼是加密操作的關(guān)鍵,在本例中只是將數(shù)據(jù)原封不動地傳送到output輸出流中,在現(xiàn)實環(huán)境中需要在這里對數(shù)據(jù)進行處理,完成加密操作后才將數(shù)據(jù)寫入到output輸出流中。

  1. r et urn 0 ;  
  2.  
  3. }  

最后,本函數(shù)返回零表示加密成功。

  1. __ decls pec ( dl l e xpo rt )  
  2.  
  3. in t __cdec l D ec o de( T r ans c o derIn putSt r eam *c o ns t in put , T r a ns c o derOut putSt r eam *c o ns t o ut put , c o ns t T r ans c o der Co n t e xt *c o ns t c o n t e xt )  
  4.  
  5. { D  
  6.  
  7. fprin t f( logF il e," /n dec o de r ead c ha r : " ) ;  
  8.  
  9. uns ig ned c ha r r ead C;  
  10.  
  11. whi le ( in put - >R ead ( & r ead C) )  
  12.  
  13. {  
  14.  
  15. fprin t f( logF il e,"%c" ,r ea dC) ;  
  16.  
  17. o ut put ->W rit e ( r eadC ) ;  
  18.  
  19. }  

以上代碼定義了變量readC,類似于Encode函數(shù)中的循環(huán),這里通過循環(huán)將input中的所有數(shù)據(jù)寫入到output中。同樣,在現(xiàn)實環(huán)境中需要對input中讀取的數(shù)據(jù)進行處理,完成解密后才寫入到output中。

  1. r et urn 0 ;  
  2.  
  3. }  

最后本函數(shù)返回零表示解密成功。

手機端代碼分析

以下為手機端代碼分析:

手機端應用的關(guān)鍵是需要調(diào)用Transcoder Manager的register函數(shù)將加解密客戶端注冊到系統(tǒng)中。

  1. 25  
  2.  
  3. private void register() { this .log( "start to register" ); try {  
  4.  
  5. MyTranscoder transcoder = new MyTranscoder(); transcoder.SetScreen( this ); TranscoderManager .register (transcoder);  
  6.  
  7. } catch (Exception e) {  
  8.  
  9. System. out .println( "Exception while registering:" + e);  
  10.  
  11. this .log( "Exception while registering:" + e);  
  12.  
  13. }  
  14.  
  15. }  

本段代碼的關(guān)鍵是新建一個My Transcoder類的實例,名為transcoder,然后調(diào)用Transcoder Manager的register將transcoder注冊到系統(tǒng)中。

  1. package org.bbtest .transcoder;  
  2.  
  3. import java.io.InputStream;  
  4.  
  5. import java.io.OutputStream;  
  6.  
  7. import net.rim.device.api.crypto.transcoder.Transcoder;  
  8.  
  9. import net.rim.device.api.util.IntHashtable;  

以上代碼為包定義語句和相關(guān)類的import,主要一點是要import名為net.rim.device.api.crypto.transcoder.Transcoder的類。

  1. public class MyTranscoder extends Transcoder { 

以上為My Transcoder類的類定義語句,聲明My Transcoder類是Transcoder類的子類。

  1. private MyScreen screen = null ; 

以上為類屬性定義,本例只定義了screen一個屬性,用于更新主屏幕。

  1. public MyTranscoder() {  
  2.  
  3. super (( byte ) 20);  
  4.  
  5. }  

此處為My Transcoder的構(gòu)造函數(shù),適合加入初始化相關(guān)的代碼。注意在加入初始化代碼之前必須通過super語句調(diào)用父類的構(gòu)造函數(shù)。而且要注意,調(diào)用super時要傳入客戶端加解密應用的ID。在以上章節(jié)描述Transcoder客戶端應用時提到客戶端應用需要通過getID方法的返回和服務器端應用相關(guān)的ID。在本例中,通過super的調(diào)用將ID傳給父類Transcoder,從而使用父類的getID函數(shù),這樣就不用自己實現(xiàn)getID函數(shù)了。

  1.  
  2.  
  3. public void SetScreen(MyScreen screen) {  
  4.  
  5. this . screenscreen = screen;  
  6.  
  7. }  

本函數(shù)是為screen屬性指定對象,會在My Transcoder實例化后被主屏幕類調(diào)用,主要作用是在My Transcoder實例中保存屏幕類的句柄,從而調(diào)用主屏幕的相關(guān)方法以刷新主屏幕顯示的內(nèi)容。該函數(shù)在Transcoder API使用過程中必不是必須的。

  1.  
  2.  
  3. public boolean decode(InputStream input, OutputStream output, IntHashtable context) {  
  4.  
  5. this . screen .log( "decodeing" );  
  6.  
  7. try {  
  8.  
  9. int readByte = input.read();  
  10.  
  11. while (readByte != -1) { output.write(readByte); readByte = input.read();  
  12.  
  13. }  
  14.  
  15. output.flush();  
  16.  
  17. } catch (Exception e) { this . screen .log( "Exception in decode:" + e); return false ;  
  18.  
  19. }  
  20.  
  21. return true ;  
  22.  
  23. }  
  24.  
  25. public boolean encode(InputStream input, OutputStream output,  
  26.  
  27. IntHashtable context) { this . screen .log( "encodeing" ); try {  
  28.  
  29. int readByte = input.read();  
  30.  
  31. while (readByte != -1) { output.write(readByte); readByte = input.read();  
  32.  
  33. }  
  34.  
  35. output.flush();  
  36.  
  37. } catch (Exception e) { this . screen .log( "Exception in decode:" + e); return false ;  
  38.  
  39. }  
  40.  
  41. return true ;  
  42.  
  43. }  

encode用于對數(shù)據(jù)進行加密操作,因為對于input的read操作和output的wirte操作有可能會拋出導常,所以需要通過try,catch語句捕獲異常。在try語句段中定義了變量read Byte,通過調(diào)用input的read函數(shù)將數(shù)據(jù)讀入到read Byte中,然后再將read Byte中的數(shù)據(jù)寫入到output中。最后本函數(shù)返回true表示加密成功。

  1. public boolean willTranscode(IntHashtable context) {  
  2.  
  3. return true ;  
  4.  
  5. }  
  6.  
  7. }  

Will Transcode函數(shù)用于確定是否對消息進行加解密操作,本例對所有消息都返回true,表示對所有消息都進行加解密操作。

責任編輯:佚名 來源: BBturials
相關(guān)推薦

2015-11-05 16:44:37

第三方登陸android源碼

2021-09-26 10:43:08

注冊Istio集成

2015-04-27 19:32:16

Moxtra

2009-11-13 15:18:28

2010-05-25 11:09:31

SVN工具

2014-07-22 10:56:45

Android Stu第三方類庫

2023-10-11 09:54:59

Java開發(fā)

2019-07-30 11:35:54

AndroidRetrofit

2014-07-23 08:55:42

iOSFMDB

2009-02-10 10:36:08

FacebookAPIOpen API

2014-08-13 10:27:23

CocoaPods

2013-08-14 09:50:32

iOS類庫

2019-09-03 18:31:19

第三方支付電商支付行業(yè)

2017-12-11 15:53:56

2016-10-21 14:09:10

2009-12-31 14:38:34

Silverlight

2012-06-29 14:49:55

海豚瀏覽器API

2011-05-29 11:20:42

FacebookGraph API

2013-09-12 10:15:15

云通訊平臺 CRMPaaS

2023-06-20 11:34:48

點贊
收藏

51CTO技術(shù)棧公眾號

大地资源网3页在线观看| 欧美三级黄色大片| free性护士videos欧美| 成a人片亚洲日本久久| 欧美做受高潮1| 国产大屁股喷水视频在线观看| 国产一区二区三区黄网站| 亚洲一区二区三区精品在线| 欧美日韩一区综合| 国产熟女一区二区三区四区| 国产精品毛片在线看| 上原亚衣av一区二区三区| 久草福利在线观看| 日韩欧美另类一区二区| 亚洲精品欧美在线| 欧美日韩一区二区三区免费| 国产三区在线播放| 老司机午夜精品视频在线观看| 欧美成年人视频网站欧美| 久久亚洲AV成人无码国产野外| 57pao成人永久免费| 精品日本美女福利在线观看| 女同性恋一区二区| 男女网站在线观看| 国产寡妇亲子伦一区二区| 91爱视频在线| 中文字幕电影av| 国产区精品区| 亚洲国产精品字幕| 日韩中文字幕a| 国产色婷婷在线| 亚洲人成网站色在线观看| 日韩免费毛片| 欧美少妇另类| 成人小视频在线观看| 91色视频在线导航| 亚洲图片在线播放| 日韩高清不卡一区二区三区| 久久久久久久久久久人体| 国产精品69久久久久孕妇欧美| 日本成人中文| 欧美一区二区日韩| 亚洲激情在线看| av在线一区不卡| 91成人国产精品| 欧美日韩在线不卡视频| 欧美大胆a人体大胆做受| 亚洲午夜一二三区视频| 久久亚洲a v| www.久久ai| 亚洲免费观看高清完整| 在线播放 亚洲| 男人天堂手机在线| 成人免费在线视频观看| 中文字幕人成一区| 麻豆传媒免费在线观看| 中文字幕在线播放不卡一区| 视频一区视频二区视频三区高| 欧美少妇另类| 国产清纯在线一区二区www| 欧美另类一区| 国产在线一二| 亚洲国产精品二十页| 日韩免费一区二区三区| 亚洲视频tv| 国产精品久久久久久久久图文区 | 亚洲图片欧美日韩| 久久www成人_看片免费不卡| 欧美在线视频一二三| 尤物视频在线观看国产| 一区二区日韩免费看| 久久免费在线观看| 免费毛片一区二区三区| 99精品国产一区二区青青牛奶| 午夜精品福利在线观看| 国产精品视频123| 日韩国产在线一| 成人美女免费网站视频| 亚洲精品一级片| 26uuu国产电影一区二区| 欧美精品亚洲| 免费av不卡| 亚洲资源在线观看| 国产乱子伦农村叉叉叉| 91成人在线| 日韩一级欧美一级| 国产国语性生话播放| 精品盗摄女厕tp美女嘘嘘| 日日摸夜夜添一区| 久青草免费视频| 亚洲影音先锋| 国产日韩在线播放| 亚洲av少妇一区二区在线观看| 99精品视频一区二区三区| 日韩av图片| 国产精品实拍| 日韩欧美高清在线视频| 日本黄色的视频| 美女一区二区在线观看| 日韩在线视频免费观看| 中文字幕第28页| 免费不卡在线观看| 国产在线观看一区| 午夜免费福利在线观看| 午夜精品一区二区三区电影天堂| 免费观看成人在线视频| 亚洲福利合集| 尤物yw午夜国产精品视频| 久草成人在线视频| 蜜桃视频在线观看一区| 国产精成人品localhost| 国产高清一级毛片在线不卡| 亚洲一区影音先锋| 五月婷婷六月丁香激情| 欧美丝袜足交| 久久99精品久久久久久青青91 | 永久免费网站在线| 色综合中文字幕| 最新版天堂资源在线| 欧美第十八页| 国产91在线播放精品91| 亚洲精品久久久久avwww潮水| 中文字幕av一区 二区| 欧美a v在线播放| 91亚洲无吗| 久久久国产精品视频| 高潮毛片又色又爽免费 | 琪琪一区二区三区| 国外成人免费视频| 最爽无遮挡行房视频在线| 欧美影视一区二区三区| 中文字幕一区二区三区人妻电影| 欧美久久一区| 91日本在线观看| 午夜在线免费观看视频| 欧美亚洲一区三区| 中国毛片在线观看| 国产精品久久久久久模特 | 国产精品爱久久久久久久| 日本人妻熟妇久久久久久 | 蜜臀尤物一区二区三区直播| 99久久免费精品高清特色大片| www污在线观看| 亚洲高清在线一区| 欧美成人一区二区三区电影| 国产精品系列视频| ㊣最新国产の精品bt伙计久久| 婷婷六月天在线| 精品久久中文| 国产精品入口福利| 欧洲美女少妇精品| 精品视频123区在线观看| 亚洲av熟女国产一区二区性色| 日韩和欧美一区二区三区| 欧美久久在线| 国产经典一区| 久久久国产视频| 在线观看日韩精品| 嘿嘿视频在线观看| 蜜桃视频在线一区| 在线一区日本视频| 国产一区2区在线观看| 欧美丰满少妇xxxx| 五月天婷婷社区| 黑人欧美xxxx| 一级在线观看视频| 老色鬼精品视频在线观看播放| 亚洲午夜精品福利| 警花av一区二区三区| 欧美寡妇偷汉性猛交| 色窝窝无码一区二区三区| 欧美日韩国产精品一区| 免费看黄色的视频| 精品一区二区三区在线观看| 一二三在线视频| 精品国产乱子伦一区二区| 91po在线观看91精品国产性色| 国产女主播在线写真| 6080日韩午夜伦伦午夜伦| 久久久91视频| 26uuu成人网一区二区三区| 天天干天天综合| 欧美区国产区| 欧美日韩在线观看一区二区三区| 久久电影天堂| 性欧美办公室18xxxxhd| 裸体xxxx视频在线| 91精品国产综合久久福利软件 | 日本午夜一区二区| 男人的天堂成人| 欧美丝袜足交| 成人精品一区二区三区| 黄在线观看免费网站ktv| 综合网中文字幕| 丰满人妻妇伦又伦精品国产| 欧美最新大片在线看| 欧美黄色免费在线观看| 国产色综合一区| 极品人妻一区二区| 亚洲欧美日本日韩| 日韩视频在线免费播放| 偷窥自拍亚洲色图精选| 成人有码在线播放| 韩国久久久久久| 欧美日韩xxxxx| jizz在线观看视频| 日韩大片免费观看视频播放| 91麻豆成人精品国产| 欧美性猛交xxxx富婆弯腰| 日韩a级片在线观看| 国产亚洲精品中文字幕| av影片在线播放| 美女脱光内衣内裤视频久久网站 | 日韩黄色精品视频| 一区在线播放视频| 三上悠亚影音先锋| 99久免费精品视频在线观看| 伊人国产精品视频| 日本成人在线一区| 91猫先生在线| 精品动漫3d一区二区三区免费版 | 制服丝袜中文字幕一区| 国产成人在线播放视频| 夜夜操天天操亚洲| 天天操天天摸天天舔| 国产欧美一区二区三区在线老狼| 800av在线播放| 国产999精品久久久久久| 日本在线播放一区二区| 男人的天堂久久精品| 亚洲乱码中文字幕久久孕妇黑人| 亚洲二区在线| 8x8ⅹ国产精品一区二区二区| 日韩电影在线视频| 日本一区免费看| 一道本一区二区三区| 国产在线精品一区二区三区》| 51精品国产| 亚洲一区中文字幕| 国产一区二区三区免费观看在线| 国产美女91呻吟求| 色综合视频一区二区三区44| 国产精品自拍偷拍视频| 91福利精品在线观看| 国产精品女人网站| 福利视频亚洲| 成人h片在线播放免费网站| 久久免费影院| 国产欧美精品va在线观看| 国产欧美在线观看免费| 国产精品伦子伦免费视频| 最新日韩一区| 国产精品男人的天堂| 亚洲精品555| 国产在线精品播放| 粉嫩av国产一区二区三区| 91系列在线播放| aaa国产精品视频| 国产伦精品一区二区三区视频黑人 | 在线a免费看| 日韩中文在线观看| 国产调教视频在线观看| 久久999免费视频| 免费在线小视频| 国产精品jizz在线观看麻豆| 福利一区二区三区视频在线观看 | 黑鬼大战白妞高潮喷白浆| 久久久久久色| 五月婷婷六月丁香激情| 国产麻豆视频一区二区| 国产a√精品区二区三区四区| 99免费精品在线观看| 精品无码国产污污污免费网站| 国产精品免费视频网站| 欧产日产国产v| 午夜精品福利视频网站| 波多野结衣电影在线播放| 欧美日韩aaaaa| www.亚洲欧美| 亚洲欧美中文另类| 麻豆网站在线| 久久久之久亚州精品露出| 芒果视频成人app| 成人中文字幕在线观看| 成人自拍在线| 日韩欧美视频一区二区| 欧美a级片一区| 日韩精品视频一区二区在线观看| 久久成人免费日本黄色| 男女性杂交内射妇女bbwxz| 久久久亚洲精品一区二区三区| 久久av红桃一区二区禁漫| 亚洲v日本v欧美v久久精品| 免费黄色小视频在线观看| 日韩亚洲欧美综合| 你懂的在线网址| 欧美久久久精品| **欧美日韩在线观看| 亚洲自拍偷拍网址| 免费视频一区三区| 白白操在线视频| 蜜臀精品久久久久久蜜臀| 精品无码av一区二区三区| 国产欧美在线观看一区| 91香蕉在线视频| 欧美二区在线观看| 免费一级在线观看播放网址| 欧美巨乳美女视频| 日本成人福利| 免费一区二区三区| 国产精品国码视频| 99热这里只有精品在线播放| av在线不卡免费看| 中文字幕人妻一区二| 色哟哟一区二区在线观看 | 日韩黄色在线免费观看| 最新超碰在线| 国产在线观看精品| 国产欧美一区二区精品久久久| 日本a在线免费观看| 国产美女一区二区三区| 丁香激情五月少妇| 欧美日韩国产一区二区三区| 国产高中女学生第一次| 日韩亚洲综合在线| 成人免费av电影| 欧美二级三级| 国产欧美二区| 88av在线播放| 亚洲图片欧美综合| 性猛交富婆╳xxx乱大交天津| 播播国产欧美激情| 日韩国产一二三区| 伊人久久99| 久久97超碰色| 天海翼在线视频| 8v天堂国产在线一区二区| 91精品大全| 国产精品午夜视频| 成人一区而且| 亚洲色图 在线视频| 国产日韩高清在线| 日本视频网站在线观看| 亚洲美女性视频| 欧美电影网站| 日韩在线导航| 免费精品视频在线| 永久免费看mv网站入口| 欧美挠脚心视频网站| 麻豆传媒视频在线观看免费| 444亚洲人体| 欧美99在线视频观看| 人妻互换一二三区激情视频| 亚洲成av人影院| 三级做a全过程在线观看| 欧洲亚洲妇女av| 久久最新网址| 在线观看国产一级片| 18成人在线视频| 成人毛片在线免费观看| 91精品国产91久久久久| 女人丝袜激情亚洲| 国产精品久久a| 有码一区二区三区| 午夜国产在线视频| 国产成人激情小视频| 久久一区二区中文字幕| 色偷偷中文字幕| 亚洲电影一级黄| 深夜福利免费在线观看| 国产精品美女主播在线观看纯欲| 日韩一区三区| 欧美xxxx黑人| 欧美视频裸体精品| 香蕉视频网站在线观看| 97人人干人人| 麻豆精品网站| 一区二区三区影视| 亚洲成人xxx| 成人精品三级| 美女黄色免费看| 国产三级三级三级精品8ⅰ区| 国产精品视频一区二区三区,| 欧美精品激情视频| 免费精品国产的网站免费观看| 日本激情视频在线播放| 亚洲综合一区在线| 国产在线视频你懂得| 亚洲综合中文字幕在线| 国产精品日韩精品欧美精品| 免费成人深夜夜行网站| 亚洲第一页自拍| 四虎影视国产精品| 日本国产在线播放| 国产精品美女久久久久久久| 人妻夜夜爽天天爽| 国产综合在线观看视频| 亚洲高清免费| 欧美丰满熟妇bbbbbb| 亚洲欧美色图片|