posts - 104,  comments - 34,  trackbacks - 0

          一.前言

               在平時運(yùn)用中,往往會遇到不同語言之間的通訊,比如php中實(shí)現(xiàn)一種加密傳輸算法,需要用Java進(jìn)行解碼,這時就要保持不同語言加密解密的一致性,才能正常通信。本文就通過Java實(shí)現(xiàn)php中mcrypt進(jìn)行des加密相同的效果。其中引入了不太被人關(guān)注的“初始化向量”,并對主要代碼進(jìn)行了注釋。

          二.Java代碼

          /**

           * 用java完成DES對稱加密

           * BlowFish 算法用來加密 64Bit 長度的字符串

           * 用 BlowFish 算法加密信息,需要兩個過程:

           * 1.密鑰預(yù)處理

           * 2.信息加密

           *

           * by tester 2010-11-04

           */

          public class BlowfishTest {

                 // 密鑰

                 public static final String ENCRYPT_KEY = "WkoxWT0kJik=";

                 // 初始化向量

                 public static final String INITIALIZATION_VECTOR = "cnBHdE9F";

                 // 轉(zhuǎn)換模式

                 public static final String TRANSFORMATION = "Blowfish/CBC/PKCS5Padding";

                 // 密鑰算法名稱

                 public static final String BLOWFISH = "Blowfish";

                 /**

                  * 加密

                  *

                  * @param key

                  *            密鑰

                  * @param text

                  *           加密文本

                  * @param initializationVector

                  *           初始化向量

                  */

                 public static String encrypt(String key, String text, String initializationVector)

                      throws Exception {

                        // 根據(jù)給定的字節(jié)數(shù)組構(gòu)造一個密鑰  Blowfish-與給定的密鑰內(nèi)容相關(guān)聯(lián)的密鑰算法的名稱

                        SecretKeySpec sksSpec = new SecretKeySpec(key.getBytes(), BLOWFISH);

                        // 使用 initializationVector 中的字節(jié)作為 IV 來構(gòu)造一個 IvParameterSpec 對象

                        AlgorithmParameterSpec iv = new IvParameterSpec(initializationVector.getBytes());

                        // 返回實(shí)現(xiàn)指定轉(zhuǎn)換的 Cipher 對象

                        Cipher cipher = Cipher.getInstance(TRANSFORMATION);

                        // 用密鑰和隨機(jī)源初始化此 Cipher

                        cipher.init(Cipher.ENCRYPT_MODE, sksSpec, iv);

                        // 加密文本

                        byte[] encrypted = cipher.doFinal(text.getBytes());

                        return new String(Hex.encodeHex(encrypted));

                 }

                 /**

                  * 解密

                  *

                  * @param key

                  *            密鑰

                  * @param text

                  *           加密文本

                  * @param initializationVector

                  *           初始化向量

                  */

                 public static String decrypt(String key, String text, String initializationVector)

                      throws Exception {

                        byte[] encrypted = null;

                        try{

                               encrypted = Hex.decodeHex(text.toCharArray());

                        } catch (Exception e)

                        {

                               e.printStackTrace();

                        }

                        SecretKeySpec skeSpect = new SecretKeySpec(key.getBytes(), BLOWFISH);

                        AlgorithmParameterSpec iv = new IvParameterSpec(initializationVector.getBytes());

                        Cipher cipher = Cipher.getInstance(TRANSFORMATION);

                        cipher.init(Cipher.DECRYPT_MODE, skeSpect, iv);

                        byte[] decrypted = cipher.doFinal(encrypted);

                        return new String(decrypted);

                 }

                 /**

                  * Base64字符解碼

                  *

                  * @param base64String

                  *            -- 被解碼字符

                  * @return 解碼后字符

                  */

                 public static String base64Decoder(String base64String) {

                        if(StringUtils.isEmpty(base64String))

                        {

                               return base64String;

                        }

                        else

                        {

                               return new String(Base64.decodeBase64(base64String));

                        }   

                 }

                 /**

                  * Base64字符編碼

                  *

                  * @param sourceString

                  *            -- 字符

                  * @return 編碼后字符

                  */

                 public static String base64Encoder(String sourceString) {

                        if(StringUtils.isEmpty(sourceString))

                        {

                               return sourceString;

                        }

                        else

                        {

                               return Base64.encodeBase64String(sourceString.getBytes());

                        } 

                 }

                 /**

                  * @param 測試方法

                  */

                 public static void main(String[] args) {

                        // TODO Auto-generated method stub

                        try {

                               String encryptStr = base64Encoder(encrypt(ENCRYPT_KEY, " tester ", INITIALIZATION_VECTOR));

                               System.out.print("tester加密后得到:" + encryptStr +""n");

                               String decryptStr = decrypt(ENCRYPT_KEY, base64Decoder(encryptStr), INITIALIZATION_VECTOR);

                               System.out.print(encryptStr+"解密后得到:"+decryptStr);

                        } catch (Exception e) {

                               // TODO Auto-generated catch block

                               e.printStackTrace();

                        }

                 }

          }

          實(shí)行結(jié)果:

          tester加密后得到:MzA2YThlZDFlNjI2MmYwYTc2Y2VlZTc5M2ZjMDQ0YjI=

          MzA2YThlZDFlNjI2MmYwYTc2Y2VlZTc5M2ZjMDQ0YjI=解密后得到:tester

          三.其他語言同類實(shí)現(xiàn)方法介紹

          Php:   string mcrypt_cbc ( int $cipher , string $key , string $data , int $mode [, string $iv ] )

          C#:    CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write)

          四.DES加密算法介紹

           DES算法為密碼體制中的對稱密碼體制,又被成為美國數(shù)據(jù)加密標(biāo)準(zhǔn),是1972年美國IBM公司研制的對稱密碼體制加密算法。其密鑰長度為56位,明文按64位進(jìn)行分組,將分組后的明文組和56位的密鑰按位替代或交換的方法形成密文組的加密方法。

          五.基本原理

              入口參數(shù)有三個:key、data、mode。 key為加密解密使用的密鑰,data為加密解密的數(shù)據(jù),mode為其工作模式。當(dāng)模式為加密模式時,明文按照64位進(jìn)行分組,形成明文組,key用于對數(shù)據(jù)加密,當(dāng)模式為解密模式時,key用于對數(shù)據(jù)解密。實(shí)際運(yùn)用中,密鑰只用到了64位中的56位,這樣才具有高的安全性。

            DES( Data Encryption Standard)算法,于1977年得到美國政府的正式許可,是一種用56位密鑰來加密64位數(shù)據(jù)的方法。雖然56位密鑰的DES算法已經(jīng)風(fēng)光不在,而且常有用Des加密的明文被破譯的報道,但是了解一下昔日美國的標(biāo)準(zhǔn)加密算法總是有益的,而且目前DES算法得到了廣泛的應(yīng)用,在某些場合,仍然發(fā)揮著余熱。

          常見加密模式介紹:

          ECB(Electronic Code Book:電碼本)

           ECB是最簡單的模式,同樣的明文分組總是加密成相同的密文分組。這對于發(fā)送單一的塊數(shù)據(jù)來說是非常好的,如密鑰。但對執(zhí)行一個加密的信息流來說不是很好,因?yàn)槿绻嗤拿魑亩啻伟l(fā)送以后,同樣的密文也會被多次發(fā)送。
          ECB最大的弱點(diǎn)是對每一個塊用相同的方式進(jìn)行加密。如果我們的密鑰或者數(shù)據(jù)不斷發(fā)生變化,ECB是完全安全的。但是如果類似的塊經(jīng)過同樣的密鑰加密發(fā)出以后,攻擊者可能獲得一些我們并不想讓別人知道的信息。

          CBC(Cipher Block Chaining:密碼分組鏈接)  
          CBC模式改變了加密方式,同樣的明文分組不一定加密或解密同樣的密文塊,因此解決了ECB存在的主要問題。CBC使用前一分組的信息加密當(dāng)前分組。因此和ECB模式大不相同。這個方法依然存在問題,那就是相同的信息仍然加密成相同的密文,因?yàn)樗械姆纸M是同時變成密文分組的。為了解決這個問題,我們引入一個Initialization Vector(初始化向量),也就是前不久有人問到的IV問題。IV僅僅是一個初始化加密程序的隨機(jī)數(shù)。它無需秘密保存,但隊(duì)每一個信息來說它都是不同的,通過這個方式,即使有兩條相同的信息,只要他們有不同的IV,那么他們加密后的密文也是不同的。從這個意義上來說,初始化向量無疑就和口令加密過程中使用的鹽值是一樣的。
          CBC很適合文本傳輸,但它每一次都需要傳送一個完整的數(shù)據(jù)塊,一般選8個字符。

          CFB(Cipher FeedBack:密碼反饋)  
          CFB的工作方式與CBC類似,但它可以執(zhí)行更小的數(shù)據(jù)塊,典型的有8位,這非常適合加密像聊天對話這樣的信息,因?yàn)槊看慰梢园l(fā)送單一的字節(jié)數(shù)據(jù)塊。
          和CBC一樣,CFB也需要一個IV,且相同及鑰發(fā)送的每條信息的IV都必須是唯一的。

          OFB(Output FeedBack:輸出反饋)

           OFB除了在傳輸中能給數(shù)據(jù)提供更好的保護(hù),防止數(shù)據(jù)丟失外,其他和CFB類似。密文中一位出錯,也只造成明文中的一位出錯,其他的方式會造成整個塊丟失。

          本文采用的是CBC(Cipher Block Chaining:密碼分組鏈接)的模式。

           

          結(jié)語:Ok,今天的學(xué)習(xí)就到這里,希望對大家有幫助。

          posted on 2011-04-28 19:52 末日風(fēng)情 閱讀(2403) 評論(0)  編輯  收藏 所屬分類: java編程
          <2011年4月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 阳信县| 宁陵县| 丰台区| 玛沁县| 平果县| 银川市| 宁蒗| 阿拉尔市| 阿鲁科尔沁旗| 金阳县| 蓝田县| 泾源县| 江门市| 湘潭县| 尚义县| 洛隆县| 舞阳县| 南开区| 高州市| 潞城市| 井研县| 花莲市| 南川市| 区。| 信丰县| 达孜县| 金华市| 西林县| 灵武市| 新河县| 司法| 西青区| 富蕴县| 龙胜| 甘谷县| 贡嘎县| 南康市| 洞头县| 平定县| 安宁市| 德钦县|