Dict.CN 在線詞典, 英語學(xué)習(xí), 在線翻譯

          都市淘沙者

          荔枝FM Everyone can be host

          統(tǒng)計(jì)

          留言簿(23)

          積分與排名

          優(yōu)秀學(xué)習(xí)網(wǎng)站

          友情連接

          閱讀排行榜

          評(píng)論排行榜

          電子商務(wù)使用數(shù)據(jù)加密來保護(hù)數(shù)據(jù)庫(kù) (二)

          電子商務(wù)使用數(shù)據(jù)加密來保護(hù)數(shù)據(jù)庫(kù)?(二)
          上篇講解了一些理論上的內(nèi)容,這次我們?cè)敿?xì)介紹一下例子:

          例如,我們創(chuàng)建一個(gè)類DESUtil.java

          按照上次講的,我要首先要?jiǎng)?chuàng)建一個(gè)密鑰,所以先增加一個(gè)方法,用來創(chuàng)建DES密鑰。為了使用方便,我們暫時(shí)把所有的方法寫成靜態(tài)方法。
          //filename是要保存的文件路徑
          public?static?void?createKey(String?filename)?throws?Exception{
          //生成一個(gè)可信任的隨機(jī)數(shù)源
          SecureRandom?sr?=?new?SecureRandom();
          //為我們選擇的DES算法生成一個(gè)KeyGenerator對(duì)象
          KeyGenerator?kg?=?KeyGenerator.getInstance("DES");
          kg.init(sr);
          //生成密鑰
          Key?key?=?kg.generateKey();
          //將密鑰數(shù)據(jù)保存為文件供以后使用
          writeFile(key,filename); //稍候講解
          }

          好了,我們可以通過上面的方法生成密鑰了。
          因?yàn)槲覀兛赡軙?huì)在不同的地方調(diào)用加密或者解密的方法,所以我們必須把生成密鑰的存儲(chǔ)在一個(gè)文件中,推薦存儲(chǔ)到應(yīng)用的/WEB-INF/的某個(gè)目錄下,因?yàn)槟莻€(gè)目錄只由自己的程序調(diào)用,不能通過URL訪問,所以更安全。接下來我們要寫兩個(gè)方法,一個(gè)將密鑰存儲(chǔ)到文件,另一個(gè)則是在加密或者解密的方法中讀出密鑰進(jìn)行加密或者解密。

          //filename是密鑰存儲(chǔ)的路徑,msg是我們用第一個(gè)方法生成的密鑰
          public?static?void?writeFile(Key?msg,?String?filePath)?{
          try?{
          File?file?=?new?File(filePath);
          if?(file.exists())?{
          file.delete();
          }
          FileOutputStream?wf?=?new?FileOutputStream(file);
          ObjectOutputStream?out?=?new?ObjectOutputStream(wf);
          out.writeObject(msg);
          out.close();
          file?=?null;
          wf?=?null;
          }?catch?(IOException?e)?{
          debug(e.getMessage());
          }
          }
          //filename是密鑰存儲(chǔ)的路徑
          public?static?Key?readFile(String?filePath)?{
          Key?key?=?null;
          try?{
          File?f?=?new?File(filePath);
          if?(f.exists())?{
          FileInputStream?bw?=?new?FileInputStream(f);
          ObjectInputStream?in?=?new?ObjectInputStream(bw);
          key?=?(Key)in.readObject();
          in.close();
          bw?=?null;
          }
          f?=?null;
          }?catch?(Exception?e)?{
          debug(e.getMessage());
          }
          return?key;
          }

          這里我們直接把密鑰對(duì)象整個(gè)存到了文件中,當(dāng)然也可以用字節(jié)的方式存儲(chǔ),但是中間可以會(huì)有些小麻煩噢!

          好了,現(xiàn)在密鑰的問題也解決了,我們接下來的工作就是寫加密和解決的方法了。

          //str?要加密的字節(jié)數(shù)組
          public?static?byte[]?DataEncrypt(byte[]?str,String?filename)?throws?Exception{
          //
          SecretKey?key?=?(SecretKey)readFile(filename);
          //Cipher對(duì)象實(shí)際完成加密操作
          Cipher?cipher?=?Cipher.getInstance("DES");
          //用密鑰初始化Cipher對(duì)象
          cipher.init(Cipher.ENCRYPT_MODE,?key);
          //執(zhí)行加密操作
          byte[]?encryptedData?=?cipher.doFinal(str);
          //
          return?encryptedData;
          }
          //str?要解密的字節(jié)數(shù)組
          public?static?byte[]?DataDecrypt(byte[]?str,String?filename)?throws?Exception{
          //
          SecretKey?key?=?(SecretKey)readFile(filename);
          //Cipher對(duì)象實(shí)際完成加密操作
          Cipher?cipher?=?Cipher.getInstance("DES");
          //用密鑰初始化Cipher對(duì)象
          cipher.init(Cipher.DECRYPT_MODE,?key);
          //執(zhí)行加密操作
          byte[]?encryptedData?=?cipher.doFinal(str);
          //
          return?encryptedData;
          }


          簡(jiǎn)單吧,我們已經(jīng)成功的創(chuàng)建了DES加密,解密的類了。測(cè)試一下吧!

          public?static?void?main(String[]?args)?{
          String?filename?=?"c:/des.key";
          String?str?=?"0109103746028";
          System.out.print("source="+str);
          try?{
          DESUtil.createKey(filename);
          //
          byte[]?enstr?=?DESUtil.DataEncrypt(str.getBytes(),filename);
          str?=?new?String(enstr);//加密后的字串
          System.out.print("encrypt="?+?str);
          //
          byte[]?destr?=?DESUtil.DataDecrypt(str.getBytes(),filename);
          str?=?new?String(destr);//解密后的字串
          System.out.print("decrypt="?+?str);
          }?catch?(Exception?e)?{
          e.printStackTrace();
          }
          debug("ok");
          }

          如果沒有定錯(cuò)的話,一定報(bào)錯(cuò)了:?javax.crypto.BadPaddingException:?Given?final?block?not?properly?padded
          怎么回事,都是按照你的寫的,怎么會(huì)不對(duì)呢?仔細(xì)分析一下,不難發(fā)現(xiàn),該異常是在解密的時(shí)候拋出的,加密的方法沒有問題。

          但是兩個(gè)方法的唯一差別是Cipher對(duì)象的模式不一樣,這就排除了程序?qū)戝e(cuò)的可能性。再看一下異常的揭示信息,大概的意思是:提供的字塊不符合填補(bǔ)的。什么意思???原來在用DES加密的時(shí)候,最后一位長(zhǎng)度不足64的,它會(huì)自動(dòng)填補(bǔ)到64,那么在我們進(jìn)行字節(jié)數(shù)組到字串的轉(zhuǎn)化過程中,可以把它填補(bǔ)的不可見字符改變了,所以引發(fā)系統(tǒng)拋出異常。問題找到,怎么解決呢?大家還記得郵件傳輸通常會(huì)把一些信息編碼保存,對(duì)了,就是Base64,那樣保證了信息的完整性,所以我們就是利用一下下了。為了方便使用,我們?cè)賹懸粋€(gè)新的方法封裝一下原來的方法:
          //
          public?static?String?DataEncrypt(String?str){
          String?encrypt?=?null;
          try{
          byte[]?ret?=?DataEncrypt(str.getBytes("UTF-8"),filename);
          encrypt?=?new?String(Base64.encode(ret),"UTF-8");
          }catch(Exception?e){
          System.out.print(e);
          encrypt?=?str;
          }
          return?encrypt;
          }
          //
          public?static?String?DataDecrypt(String?str){
          String?decrypt?=?null;
          try{
          byte[]?ret?=??DataDecrypt(Base64.decode(str.getBytes("UTF-8")),filename);
          decrypt?=??new?String(ret,"UTF-8");
          }catch(Exception?e){
          System.out.print(e);
          decrypt?=?str;
          }
          return?decrypt;
          }

          我們把方法的參數(shù)改成了字串,但是為什么要用UTF-8呢?不指定它的字節(jié)格式不行嗎?大家知道,UTF-8是國(guó)際通用的字符編碼,用它傳輸任何字串都不會(huì)有問題,通過它也可以很完美的解決J2EE的中文問題!所以我們最好用UTF-8編碼,以減少不必要的麻煩。

          注意,上面方法中當(dāng)加密或者解密過程中,程序拋出異常,將返回原值,使得在調(diào)用方法失敗時(shí)更方便的找出錯(cuò)誤。

          大家也可以利用其它的密鑰,進(jìn)行不同地方的加密解埽?

          總結(jié):DES是一個(gè)相對(duì)比較老的加密算法,對(duì)于現(xiàn)在也不是最安全的,所以大家也可以利用別的加密算法進(jìn)行加密解密,以得到更安全的系統(tǒng)。

          附:
          DESUtil.java及Base64.java的源文件

          posted on 2006-12-16 12:07 都市淘沙者 閱讀(329) 評(píng)論(0)  編輯  收藏 所屬分類: 加密解密/其他分類

          主站蜘蛛池模板: 专栏| 敦煌市| 长武县| 苍溪县| 南通市| 清河县| 遵义县| 家居| 湖州市| 宜君县| 唐海县| 平凉市| 梅河口市| 兖州市| 洪雅县| 玛沁县| 巴青县| 彭阳县| 洛川县| 津南区| 湖州市| 荃湾区| 门源| 云南省| 通许县| 柳河县| 富平县| 郓城县| 临汾市| 灵寿县| 兴业县| 珠海市| 邯郸市| 靖安县| 镇宁| 象山县| 江川县| 白沙| 垦利县| 澄迈县| 麦盖提县|