<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    當(dāng)柳上原的風(fēng)吹向天際的時(shí)候...

    真正的快樂來源于創(chuàng)造

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks

    #

    MD5是消息摘要算法的一種,它和SHA,HMAC是消息摘要算法的主要代表,其前身有MD2,MD3,MD4算法。
    消息摘要算法又稱為散列算法,其不可破解的核心在于散列函數(shù)的單向性,即可以通過散列函數(shù)得到結(jié)果,卻不可能通過結(jié)果反推出其原始信息。這是消息摘要算法的安全性根本所在。如果用戶輸入的密碼是123456789,則會(huì)得到25f9e794323b453885f5181f1b624d0這樣的結(jié)果;如果有人拿到25f9e794323b453885f5181f1b624d0這樣的結(jié)果,他是不可能反推出密碼123456789的。
    但是,總所周知的是,MD5已經(jīng)被我國(guó)山東大學(xué)王小云教授攻破了。他是怎么做到這不可能的事呢?當(dāng)然不是反推,而是使用的碰撞算法,具體來說就是,拿到25f9e794323b453885f5181f1b624d0這樣的結(jié)果,用多種精心設(shè)計(jì)的字符串去試試,總有一個(gè)字符串經(jīng)MD5加密后能得到25f9e794323b453885f5181f1b624d0這樣的結(jié)果,這個(gè)字符串也許是真實(shí)密碼,也是是別的,但它加密后可以得到和123456789加密后一樣的效果。這就意味著,你給自己設(shè)定的密碼,別人通過其他密碼也可能通過驗(yàn)證!
    其原因還是在于散列函數(shù),不同的輸入通過散列函數(shù)可能得到同一結(jié)果,雖然這個(gè)可能性較小。王教授成果的意義在于,以前號(hào)稱用全世界所有計(jì)算機(jī)算一百年不能做到的,用他的辦法用一臺(tái)普通微機(jī)在數(shù)個(gè)小時(shí)內(nèi)就能做到。這個(gè)很了不起,諸位如果有意可以去當(dāng)他的研究生,這樣就知道是怎么做的了。
    那么,MD5還有存在的價(jià)值嗎。當(dāng)然有,因?yàn)槠平庹咭平獬晒τ腥齻€(gè)必要條件,一,知道算法;二,知道密鑰;三,有大量數(shù)據(jù)供測(cè)試。如果把幾種其它算法和MD5混合,破解者就容易困惑,再加上時(shí)間限制,破解也不是件容易的事。最后,還有理論上不可能破解的量子密碼,如果它能實(shí)用化,則能達(dá)到真正意義上的不可破解。


    posted @ 2010-12-08 18:58 何楊 閱讀(412) | 評(píng)論 (2)編輯 收藏

    密碼學(xué)的加密算法可分為 單向加密算法,對(duì)稱加密算法和非對(duì)稱加密算法三類。
    • 單向加密算法是數(shù)據(jù)完整性驗(yàn)證的常用算法,MD5SHA是單向加密算法的代表;
    • 對(duì)稱加密算法是數(shù)據(jù)存儲(chǔ)加密的常用算法,DESAES是對(duì)稱加密算法的代表;
    • 非對(duì)稱加密算法是數(shù)據(jù)傳輸加密的常用算法,RSA是非對(duì)稱加密算法的代表。對(duì)稱加密算法也可以用作數(shù)據(jù)傳輸加密,但非對(duì)稱加密算法在密鑰管理方面更有優(yōu)勢(shì),在安全級(jí)別上更高,只是時(shí)間效率上不如對(duì)稱加密算法。

    JAVA API對(duì)密碼學(xué)的支持
    • MessageDigest類,可以構(gòu)建MD5,SHA兩種加密算法;
    • Mac類可以構(gòu)建HMAC加密算法;
    • Cipher類可以構(gòu)建多種加密算法,如DES,AES,RSA,DSA,DH等;
    • Signature類可用于數(shù)字簽名和簽名驗(yàn)證;
    • Certificate類可用于操作證書。

    posted @ 2010-12-05 14:24 何楊 閱讀(219) | 評(píng)論 (0)編輯 收藏

    本版新增功能:
    1.增加對(duì)DB2數(shù)據(jù)庫的支持。
    2.過濾器不區(qū)分大小寫。
    3.取消了歡迎窗口。

    下載地址:
    http://www.box.net/shared/0flunl0zul

    Softonic下載頁面:
    http://sqltoolbox.softonic.cn/

    概述

    SqlToolBox是一款純綠色的免費(fèi)數(shù)據(jù)庫客戶端軟件,基于Java Swing編制而成,旨在于為開發(fā)人員,系統(tǒng)工程師和數(shù)據(jù)庫管理員提供一種通用方便和快捷的數(shù)據(jù)庫操作工具,使他們擺脫需要學(xué)習(xí)掌握使用多種數(shù)據(jù)庫客戶端 的苦惱,并減輕他們?nèi)粘2僮鲾?shù)據(jù)庫和編寫Sql語句的任務(wù)量,幫助他們把精力投入到解決更有意義的問題上去。

    SqlToolBox現(xiàn)有功能

    1. 能連接到MySql,Oracle,Ms Sql Server和DB2四種數(shù)據(jù)庫。
    2. 連接到數(shù)據(jù)庫后,會(huì)提供數(shù)據(jù)庫Schema和表的樹視圖以便用戶進(jìn)行瀏覽和查找,另外還提供了一個(gè)過濾器幫助用戶縮小查找范圍。
    3. 用戶能自動(dòng)快速獲取單表的創(chuàng)建,查詢,更新,刪除,建表語句,整表全部數(shù)據(jù)插入語句,單表對(duì)應(yīng)Pojo類和單表的Hibernate映射文件等常用文字,且可借此構(gòu)造更復(fù)雜的Sql語句。
    4. 能執(zhí)行Sql語句并顯示執(zhí)行結(jié)果,如果是查詢語句會(huì)以表格形式顯示結(jié)果,還提供CSV形式數(shù)據(jù)下載;如果是非查詢語句或是錯(cuò)誤的查詢語句則會(huì)以文字形式告知用戶。
    5. 在用戶輸入Sql語句的過程中提供Sql語法高亮功能,以助于Sql語句的識(shí)別。
    6. 提供Sql格式化功能以助于Sql語句的識(shí)別和整理。
    7. 提供Redo/Undo,Shift整體退格進(jìn)格,大小寫轉(zhuǎn)化,將Sql語句用StringBuilder包容以及將Sql語句中關(guān)鍵字大寫表示等常用文字編輯功能。這些都能幫助程序員在程序中書寫Sql語句。
    8. 能保存和記憶數(shù)據(jù)庫信息,以便下次打開。

    運(yùn)行SqlToolBox有何前提條件?

    將SqlToolBox運(yùn)行起來的唯一前提是安裝JDK6或以上版本。

    SqlToolBox需要安裝嗎?

    SqlToolBox是一款純綠色軟件,它對(duì)您的系統(tǒng)不做出任何更改,因此不需要安裝和卸載。

    SqlToolBox安全嗎?

    由于軟件使用Java編寫而成,它本身就具有較高的安全性。此外作者保證在SqlToolBox整個(gè)系列中都不會(huì)加入病毒,木馬,插件等壞東西。

    如何運(yùn)行SqlToolBox?

    解開下載包,然后雙擊run.bat即可。

    在Unix/Linux下如何運(yùn)行SqlToolBox?

    除了也需要安裝JDK外,您還需要參照run.bat寫一份腳本,然后執(zhí)行它。

    如何使用SqlToolBox打開一個(gè)數(shù)據(jù)庫?

    程序運(yùn)行起來后,您將看到一個(gè)輸入數(shù)據(jù)庫信息的對(duì)話框,請(qǐng)依次填入數(shù)據(jù)庫所在機(jī)器的IP地址,數(shù)據(jù)庫的庫名稱,選擇數(shù)據(jù)庫的類型以及輸入登錄數(shù)據(jù)庫的用戶 名和密碼等必要信息。此后再點(diǎn)擊“連接數(shù)據(jù)庫”按鈕,程序?qū)⒋蜷_數(shù)據(jù)庫。如果您將以上信息填錯(cuò)也不要緊,程序會(huì)提示哪里出現(xiàn)了問題。此外您可以在登錄前點(diǎn) 擊“測(cè)試連接”按鈕,程序也會(huì)告訴您是否能連接到指定的數(shù)據(jù)庫。

    打開數(shù)據(jù)庫后程序左邊部分如何使用?

    成功連接到數(shù)據(jù)庫以后,數(shù)據(jù)庫的Schema和table結(jié)構(gòu)會(huì)在畫面的左邊以樹的形式展現(xiàn)出來,如果展現(xiàn)的內(nèi)容過多,您還可以在上方的“過濾器”輸入欄 中輸入關(guān)鍵字以縮小展現(xiàn)范圍。在這顆樹中,表格(table)是以小圓點(diǎn)的方式展現(xiàn)的,左鍵點(diǎn)擊這個(gè)圓點(diǎn),程序?qū)⒃谟覀?cè)打開一個(gè)Sql語句操作窗口,并執(zhí) 行“select * from table”語句,最后在下方以表格的形式展現(xiàn)給您;如果您用右鍵點(diǎn)擊這個(gè)圓點(diǎn),程序?qū)棾鲆粋€(gè)右鍵菜單,選擇其中的項(xiàng)目您將可以在右邊的Sql語句操作 窗口中得到單表的字段信息,創(chuàng)建(insert),查詢(select),更新(update),刪除語句(delete)及建表語句(create table),單表對(duì)應(yīng)Pojo文件,單表的Hibernate映射文件等文字。

    打開數(shù)據(jù)庫后程序右邊部分是如何使用的?

    用左右鍵點(diǎn)擊表格后,您將在右側(cè)看到一個(gè)“Sql語句操作窗口”,它分成三部分:工具欄菜單,輸入窗口和輸出窗口。輸入窗口是用以輸入,編輯和整理Sql 語句的;工具欄菜單中的一大排按鈕都是為編輯處理輸入窗口中的文字而準(zhǔn)備的;輸出窗口則是展示Sql語句執(zhí)行后的結(jié)果的,如果是查詢語句,它會(huì)以表格的形 式告知您查詢的結(jié)果,如果是其它語句,它會(huì)以文字的形式告知。通常的操作手法是,先在輸入窗口中用鼠標(biāo)選中您要操作的文本,再在工具欄菜單中點(diǎn)擊執(zhí)行特定 操作的按鈕,然后在下方的輸出窗口中就能看到具體的結(jié)果,當(dāng)然如果僅是文本編輯操作的話輸出窗口是不會(huì)有反應(yīng)的。

    如何執(zhí)行Sql語句?

    程序員和數(shù)據(jù)庫管理員總是習(xí)慣使用語句來操作數(shù)據(jù)庫,這也是本軟件的最重要功能之一。執(zhí)行Sql語句的過程具體來說是這樣做的,首先,在輸入窗口輸入您向 執(zhí)行的Sql語句,如“select * from table”之類,當(dāng)然您更可以通過表格的右鍵菜單來獲得常用的sql語句(在輸入或是粘貼文本的過程中,Sql語句中的關(guān)鍵字會(huì)以藍(lán)色顯示,這是語法高 亮功能所致);其次,你需要選中你想執(zhí)行的文本,再點(diǎn)擊工具欄菜單中的向右三角形按鈕,這段文本將得到執(zhí)行,執(zhí)行結(jié)果將在下方的輸出窗口得到展示。如果您 執(zhí)行的是查詢語句,輸出窗口將以表格的形式列出查詢結(jié)果集的字段和內(nèi)容;如果您執(zhí)行的是刪除,更新,添加,修改表等語句或是執(zhí)行錯(cuò)誤的Sql文本,輸出窗 口將以文本形式告知執(zhí)行結(jié)果。另外工具欄菜單中的雙向右三角形按鈕用于批量執(zhí)行Sql語句,它以分號(hào)“;”來作為每段Sql的分隔標(biāo)志,然后分別執(zhí)行每 段。

    如何快速調(diào)整對(duì)執(zhí)行查詢語句后得到的表格列寬度?

    如果您想自動(dòng)調(diào)整某列的寬度,可以雙擊這列的表頭,此后這列的寬度會(huì)根據(jù)這列的最長(zhǎng)文字進(jìn)行調(diào)整;您還可以在表格上點(diǎn)擊右鍵,選擇“調(diào)整列寬為最適合狀態(tài)”一項(xiàng),那么所有的列寬都會(huì)進(jìn)行調(diào)整。

    如何得到執(zhí)行查詢語句后得到的表格的內(nèi)容?

    您還可以在表格上點(diǎn)擊右鍵,選擇“下載表格為CSV文件”一項(xiàng),此后查詢語句和得到的結(jié)果都會(huì)被放入一個(gè)CSV文件中。CSV是一中文本文件,但您可以用Excel打開它,也會(huì)得到xls文件一樣的效果。

    在新增或是刪除一張表后,在左邊的樹中為什么沒有相應(yīng)的變化?

    新增或是刪除一張表后,您需要手動(dòng)執(zhí)行一下左上方的更新按鈕(最上方的大圖標(biāo)中第一個(gè)),此后程序會(huì)重新載入數(shù)據(jù)庫的Schema和table,這樣您剛才對(duì)表格進(jìn)行增刪操作就能體現(xiàn)出來。

    如果我需要常打開數(shù)據(jù)庫進(jìn)行操作或是需要常操作多個(gè)數(shù)據(jù)庫,程序能為我提供那些便利?

    本軟件有記憶功能,如果您正確連接到一個(gè)數(shù)據(jù)庫,那么相應(yīng)的信息如IP地址,數(shù)據(jù)庫名,數(shù)據(jù)庫類型,連接數(shù)據(jù)庫的用戶名和密碼都會(huì)被記憶下來,這樣下次打 開時(shí)就不用重復(fù)輸入了。如果您需要常操作多個(gè)數(shù)據(jù)庫,您可以通過保存按鈕(最上方五個(gè)大圖標(biāo)中的第二個(gè))將數(shù)據(jù)庫信息保存成XML文件,這樣在登錄畫面中 就可以通過“打開文件按鈕”得到相應(yīng)的數(shù)據(jù)庫信息。

    如果我有想法和建議,如何與作者聯(lián)系?

    首先,您可以點(diǎn)擊程序上方的信封按鈕,通過郵件heyang78@gmail.com和我聯(lián)系,我會(huì)樂于回復(fù)您的郵件并會(huì)認(rèn)真考慮您提出的想法和建議;其次,您還可以通過QQ和我聯(lián)系,我的Q號(hào)是805985315;其三,我的MSN是junglesong_5@gmail.com,通過MSN也能找到我;最后,歡迎您登錄我的博客http://heyang.blogjava.net,如果SqlToolBox有所變化,我會(huì)在第一時(shí)間在博客上公告。

    感謝名單

    SqlToolBox的成長(zhǎng)離不開以下人士的建議,激勵(lì)和幫助,在此謹(jǐn)向他們表示誠摯的謝意:
    • danielxu(關(guān)于jtds-1.2.2.jar的添加)
    • creasure(關(guān)于開源的建議)
    • Always BaNg.(關(guān)于語法高亮)
    • mircle(關(guān)于提升加載數(shù)據(jù)庫對(duì)象的性能)
    • willim2000(他也做了一個(gè)類型相同的軟件)
    • ytfulz(提供連接SqlServer的連接測(cè)試以,改變輸出表格形式,調(diào)整輸出表格列寬的建議)
    • 王宏亮(提供將程序和JRE整體打包的建議)
    • 朱儉(關(guān)于幫助窗口只打開一個(gè)的建議)
    • ☆振興中華☆(關(guān)于選擇數(shù)據(jù)表的建議)


    posted @ 2010-12-03 19:25 何楊 閱讀(1223) | 評(píng)論 (4)編輯 收藏

    安裝步驟:
    1.到http://sourceforge.jp/projects/amateras/releases/?package_id=4435 去下載 AmaterasUML_1.3.2.zip
    2.下載完畢后,解開壓縮包,將其中三個(gè)jar文件拷貝到你的Eclipse目錄的plugins目錄下。
    3.啟動(dòng)或者重啟您的Eclipse。

    如何使用:
    1.點(diǎn)擊Eclipse的菜單"File"--"New"--"Others"。


    2.找到Amateras UML一項(xiàng),選擇你要繪制的UML圖類型。


    3.選擇一個(gè)要存儲(chǔ)UML圖文件的文件夾。


    4.好了,可以開始畫了。



    我是在JavaEye看人介紹后裝的,用了感覺確實(shí)不錯(cuò),Visio可以見回收站去了。

    posted @ 2010-12-02 14:29 何楊 閱讀(1702) | 評(píng)論 (0)編輯 收藏

    按:以下文字涉及RSA對(duì)WebService傳遞的數(shù)據(jù)的加密解密,如果您已經(jīng)熟知RSA或是有其它更好的方法請(qǐng)不要往下看以免浪費(fèi)時(shí)間.

    WebService采用的協(xié)議是SOAP,它基于HTTP,而HTTP是明文方式,也就是說,采用WebService傳遞的數(shù)據(jù)是明文的。如果是天氣預(yù)報(bào)這種公開的只讀信息的WebService無所謂,如果涉及寫入或是和私密數(shù)據(jù)相關(guān),那么明文傳遞就有很大的潛在危險(xiǎn)性,必須加以遏止。

    一般來說有兩種方法,一是采用https加密的方式,另一種是用非對(duì)稱加密算法對(duì)數(shù)據(jù)加密,下文提到的RSA就是第二種。

    使用RSA對(duì)WebService傳遞的信息加密解密的基本思想是:服務(wù)器端提供一個(gè)WebService方法byte[] getServerPublicKey(),客戶端可以以此得到服務(wù)器端的公鑰,然后使用服務(wù)器端的公鑰對(duì)要傳出去的數(shù)據(jù)進(jìn)行RSA加密,并附帶以自己的公鑰;服務(wù)器端得到客戶端的請(qǐng)求后,先用自己的私鑰解密客戶端送來的數(shù)據(jù),得到處理結(jié)果后用客戶端提供的公鑰加密,然后傳回;客戶端得到服務(wù)器端的返回?cái)?shù)據(jù)后,用自己的私鑰進(jìn)行解密,最終得到了服務(wù)器端的真實(shí)數(shù)據(jù)。服務(wù)器端和客戶端各自保存自己的RSA私鑰用于解密,提供給對(duì)方RSA公鑰進(jìn)行加密,這樣中間傳遞的信息就安全了。

    加密解密示意順序圖:


    下面是服務(wù)器端實(shí)現(xiàn)類的代碼:
    package com.heyang;


    public class ServiceImpl implements IService{
        @Override
        
    public byte[] getResonse(byte[] params, byte[] clientPublicKey) {
            
    try {
                
    // 使用自己的私鑰解密客戶端用服務(wù)器端公鑰加密的數(shù)據(jù)
                String decryptString=SecurityUtil.getCoder().getDecryptString(params);
                
                
    // 要返回的結(jié)果
                String response="你好!"+decryptString;
                
                
    // 使用客戶端提供的公鑰對(duì)返回的數(shù)據(jù)進(jìn)行加密
                byte[] retval=SecurityUtil.getCoder().getEncryptArray(response, clientPublicKey);
                
                
    return retval;
            } 
    catch (Exception e) {
                e.printStackTrace();
                
                
    return null;
            }
        }

        @Override
        
    public byte[] getServerPublicKey() {
            
    return SecurityUtil.getCoder().getPublicKey();
        }
    }


    客戶端調(diào)用服務(wù)器端的代碼:
    package com.heyang;

    import org.codehaus.xfire.XFireFactory;
    import org.codehaus.xfire.client.XFireProxyFactory;
    import org.codehaus.xfire.service.Service;
    import org.codehaus.xfire.service.binding.ObjectServiceFactory;

    public class Test {
        
    public static void main(String[] args) {
            Service srvcModel 
    = new ObjectServiceFactory().create(IService.class);
            XFireProxyFactory factory 
    = new XFireProxyFactory(XFireFactory
                    .newInstance().getXFire());

            String helloWorldURL 
    = "http://localhost:8080/XfireSample/services/hello";
            
    try {
                IService srvc 
    = (IService) factory.create(srvcModel, helloWorldURL);

                
    // 得到服務(wù)器端的公鑰
                byte[] serverPublicKey=srvc.getServerPublicKey();
                System.out.print(
    "從服務(wù)器端得到的公鑰為:");
                
    for(byte b:serverPublicKey){
                    System.out.print(b);
                }
                System.out.println();
                
                
                RSASecurityCoder coder
    =SecurityUtil.getCoder();
                String requestString
    ="世界";
                
                
    // 使用服務(wù)器端的公鑰對(duì)要傳出去的數(shù)據(jù)進(jìn)行加密
                byte[] params=coder.getEncryptArray(requestString, serverPublicKey);
                
                
    // 得到服務(wù)器端的返回結(jié)果
                byte[] responseArray=srvc.getResonse(params, coder.getPublicKey());
                
                
    // 使用自己的私鑰進(jìn)行解密
                String responseString=coder.getDecryptString(responseArray);
                System.out.println(
    "從服務(wù)器端返回的字符串結(jié)果是:"+responseString);
            } 
    catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    輸出的結(jié)果為:
    從服務(wù)器端得到的公鑰為:48-127-9748136942-12272-122-913111503-127-115048-127-1192-127-1270-575108-121578675121-687-32-1165359-2586-50-127114-24-6769-17-128115114982868-11550-121-111-69-494021-48-22-5844-37-8645-115-125-984651-344761-117-7875-34115-101-119164666123-4211-13-103-62-30-587926842-12338-32-91-24-75-1177128103-12-71108-121-122112-712-1089753-2691-7863-6385-41-10210782-8784120344-69-90474108-3661-47089-1261812510046-123-3910723101
    從服務(wù)器端返回的字符串結(jié)果是:你好!世界

    服務(wù)器端和客戶端使用的RSA加密解密類代碼:
    package com.heyang;

    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;

    import javax.crypto.Cipher;

    /**
     * RSA加密解密類
     * 說明:
     * 作者:何楊(heyang78@gmail.com)
     * 創(chuàng)建時(shí)間:2010-12-1 下午06:14:38
     * 修改時(shí)間:2010-12-1 下午06:14:38
     
    */
    public class RSASecurityCoder{
        
    // 非對(duì)稱加密密鑰算法
        private static final String Algorithm="RSA";
        
        
    // 密鑰長(zhǎng)度,用來初始化
        private static final int Key_Size=1024;
        
        
    // 公鑰
        private final byte[] publicKey;
        
        
    // 私鑰
        private final byte[] privateKey;
        
        
    /**
         * 構(gòu)造函數(shù),在其中生成公鑰和私鑰
         * 
    @throws Exception
         
    */
        
    public RSASecurityCoder() throws Exception{
            
    // 得到密鑰對(duì)生成器
            KeyPairGenerator kpg=KeyPairGenerator.getInstance(Algorithm);
            kpg.initialize(Key_Size);
            
            
    // 得到密鑰對(duì)
            KeyPair kp=kpg.generateKeyPair();
            
            
    // 得到公鑰
            RSAPublicKey keyPublic=(RSAPublicKey)kp.getPublic();
            publicKey
    =keyPublic.getEncoded();
            
            
    // 得到私鑰
            RSAPrivateKey keyPrivate=(RSAPrivateKey)kp.getPrivate();
            privateKey
    =keyPrivate.getEncoded();
        }
        
        
    /**
         * 用公鑰對(duì)字符串進(jìn)行加密
         * 
         * 說明:
         * 
    @param originalString
         * 
    @param publicKeyArray
         * 
    @return
         * 
    @throws Exception
         * 創(chuàng)建時(shí)間:2010-12-1 下午06:29:51
         
    */
        
    public byte[] getEncryptArray(String originalString,byte[] publicKeyArray) throws Exception{
            
    // 得到公鑰
            X509EncodedKeySpec keySpec=new X509EncodedKeySpec(publicKeyArray);
            KeyFactory kf
    =KeyFactory.getInstance(Algorithm);
            PublicKey keyPublic
    =kf.generatePublic(keySpec);
            
            
    // 加密數(shù)據(jù)
            Cipher cp=Cipher.getInstance(Algorithm);
            cp.init(Cipher.ENCRYPT_MODE, keyPublic);
            
    return cp.doFinal(originalString.getBytes());
        }
        
        
        
    /**
         * 使用私鑰進(jìn)行解密
         * 
         * 說明:
         * 
    @param encryptedDataArray
         * 
    @return
         * 
    @throws Exception
         * 創(chuàng)建時(shí)間:2010-12-1 下午06:35:28
         
    */
        
    public String getDecryptString(byte[] encryptedDataArray) throws Exception{
            
    // 得到私鑰
            PKCS8EncodedKeySpec keySpec=new PKCS8EncodedKeySpec(privateKey);
            KeyFactory kf
    =KeyFactory.getInstance(Algorithm);
            PrivateKey keyPrivate
    =kf.generatePrivate(keySpec);
            
            
    // 解密數(shù)據(jù)
            Cipher cp=Cipher.getInstance(Algorithm);
            cp.init(Cipher.DECRYPT_MODE, keyPrivate);
            
    byte[] arr=cp.doFinal(encryptedDataArray);
            
            
    // 得到解密后的字符串
            return new String(arr);
        }

        
    public byte[] getPublicKey() {
            
    return publicKey;
        }
        
        
    public static void main(String[] arr) throws Exception{
            String str
    ="你好,世界! Hello,world!";
            System.out.println(
    "準(zhǔn)備用公鑰加密的字符串為:"+str);
            
            
    // 用公鑰加密
            RSASecurityCoder rsaCoder=new RSASecurityCoder();
            
    byte[] publicKey=rsaCoder.getPublicKey();        
            
    byte[] encryptArray=rsaCoder.getEncryptArray(str, publicKey);
            
            System.out.print(
    "用公鑰加密后的結(jié)果為:");
            
    for(byte b:encryptArray){
                System.out.print(b);
            }
            System.out.println();
            
            
    // 用私鑰解密
            String str1=rsaCoder.getDecryptString(encryptArray);
            System.out.println(
    "用私鑰解密后的字符串為:"+str1);
        }
    }

    用于初始化RSASecurityCoder實(shí)例的SecurityUtil類代碼:
    package com.heyang;

    /**
     * 信息安全實(shí)用類
     * 說明:
     * 作者:何楊(heyang78@gmail.com)
     * 創(chuàng)建時(shí)間:2010-12-2 上午10:57:49
     * 修改時(shí)間:2010-12-2 上午10:57:49
     
    */
    public class SecurityUtil{
        
    // 用于加密解密的RSA編碼類
        private static RSASecurityCoder coder;
        
        
    /**
         * 初始化coder的靜態(tài)構(gòu)造子
         
    */
        
    static{
            
    try {
                coder
    =new RSASecurityCoder();
            } 
    catch (Exception e) {
                e.printStackTrace();
            }
        }

        
    public static RSASecurityCoder getCoder() {
            
    return coder;
        }
    }


    您可以從http://www.box.net/shared/cyg98xgz78 獲得上述代碼涉及到的兩個(gè)實(shí)例工程。

    好了,感謝您看到這里,希望此文字沒有耽誤您太多寶貴時(shí)間。
    posted @ 2010-12-02 11:44 何楊 閱讀(11037) | 評(píng)論 (16)編輯 收藏

    按:以下文字涉及RSA解密加密的基本操作,您如果已經(jīng)知曉就不用浪費(fèi)時(shí)間了。

    在加密解密過程中,如果加密解密雙方都使用同一密鑰,那么泄密的可能性還是存在的,無論你把這個(gè)密鑰放在代碼,文件或是數(shù)據(jù)庫中。最好是密鑰分成兩部分,公鑰提供出去給應(yīng)答者,讓它給返回的結(jié)果加密,請(qǐng)求者得到返回結(jié)果后,用自己的私鑰將其解密,公鑰和私鑰都由程序生成。這樣,客戶端和服務(wù)器端程序的所有者和編寫者都難以知道每個(gè)客戶端的私鑰是什么,從而難以破解數(shù)據(jù)。RSA就是實(shí)現(xiàn)這一想法的途徑之一。

    舉例來說,現(xiàn)在有一客戶端視圖和WebService服務(wù)器端通信,假如服務(wù)器端的響應(yīng)函數(shù)是 String getResponse(String params,byte[] publicKeyArray);兩邊程序都有下面的RSASecurityCoder類,客戶端在發(fā)送請(qǐng)求前,可以得到此類的一個(gè)實(shí)例,并得到其公鑰,然后調(diào)用服務(wù)器端的getResponse函數(shù),公鑰就是這個(gè)函數(shù)的第二個(gè)參數(shù);服務(wù)器端得到請(qǐng)求后,處理得到結(jié)果,然后用第二個(gè)參數(shù)--客戶端送來的公鑰進(jìn)行加密,然后送回結(jié)果;客戶端得到結(jié)果后用自己的私鑰進(jìn)行解密就可以了。這樣,信息在傳輸過程的安全性就有了充分的保證了。

    下面請(qǐng)看代碼:
    package com.heyang.util;

    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;

    import javax.crypto.Cipher;

    /**
     * RSA加密解密類
     * 說明:
     * 作者:何楊(heyang78@gmail.com)
     * 創(chuàng)建時(shí)間:2010-12-1 下午06:14:38
     * 修改時(shí)間:2010-12-1 下午06:14:38
     
    */
    public class RSASecurityCoder{
        
    // 非對(duì)稱加密密鑰算法
        private static final String Algorithm="RSA";
        
        
    // 密鑰長(zhǎng)度,用來初始化
        private static final int Key_Size=1024;
        
        
    // 公鑰
        private final byte[] publicKey;
        
        
    // 私鑰
        private final byte[] privateKey;
        
        
    /**
         * 構(gòu)造函數(shù),在其中生成公鑰和私鑰
         * 
    @throws Exception
         
    */
        
    public RSASecurityCoder() throws Exception{
            
    // 得到密鑰對(duì)生成器
            KeyPairGenerator kpg=KeyPairGenerator.getInstance(Algorithm);
            kpg.initialize(Key_Size);
            
            
    // 得到密鑰對(duì)
            KeyPair kp=kpg.generateKeyPair();
            
            
    // 得到公鑰
            RSAPublicKey keyPublic=(RSAPublicKey)kp.getPublic();
            publicKey
    =keyPublic.getEncoded();
            
            
    // 得到私鑰
            RSAPrivateKey keyPrivate=(RSAPrivateKey)kp.getPrivate();
            privateKey
    =keyPrivate.getEncoded();
        }
        
        
    /**
         * 用公鑰對(duì)字符串進(jìn)行加密
         * 
         * 說明:
         * 
    @param originalString
         * 
    @param publicKeyArray
         * 
    @return
         * 
    @throws Exception
         * 創(chuàng)建時(shí)間:2010-12-1 下午06:29:51
         
    */
        
    public byte[] getEncryptArray(String originalString,byte[] publicKeyArray) throws Exception{
            
    // 得到公鑰
            X509EncodedKeySpec keySpec=new X509EncodedKeySpec(publicKeyArray);
            KeyFactory kf
    =KeyFactory.getInstance(Algorithm);
            PublicKey keyPublic
    =kf.generatePublic(keySpec);
            
            
    // 加密數(shù)據(jù)
            Cipher cp=Cipher.getInstance(Algorithm);
            cp.init(Cipher.ENCRYPT_MODE, keyPublic);
            
    return cp.doFinal(originalString.getBytes());
        }
        
        
        
    /**
         * 使用私鑰進(jìn)行解密
         * 
         * 說明:
         * 
    @param encryptedDataArray
         * 
    @return
         * 
    @throws Exception
         * 創(chuàng)建時(shí)間:2010-12-1 下午06:35:28
         
    */
        
    public String getDecryptString(byte[] encryptedDataArray) throws Exception{
            
    // 得到私鑰
            PKCS8EncodedKeySpec keySpec=new PKCS8EncodedKeySpec(privateKey);
            KeyFactory kf
    =KeyFactory.getInstance(Algorithm);
            PrivateKey keyPrivate
    =kf.generatePrivate(keySpec);
            
            
    // 解密數(shù)據(jù)
            Cipher cp=Cipher.getInstance(Algorithm);
            cp.init(Cipher.DECRYPT_MODE, keyPrivate);
            
    byte[] arr=cp.doFinal(encryptedDataArray);
            
            
    // 得到解密后的字符串
            return new String(arr);
        }

        
    public byte[] getPublicKey() {
            
    return publicKey;
        }
        
        
    public static void main(String[] arr) throws Exception{
            String str
    ="你好,世界! Hello,world!";
            System.out.println(
    "準(zhǔn)備用公鑰加密的字符串為:"+str);
            
            
    // 用公鑰加密
            RSASecurityCoder rsaCoder=new RSASecurityCoder();
            
    byte[] publicKey=rsaCoder.getPublicKey();        
            
    byte[] encryptArray=rsaCoder.getEncryptArray(str, publicKey);
            
            System.out.print(
    "用公鑰加密后的結(jié)果為:");
            
    for(byte b:encryptArray){
                System.out.print(b);
            }
            System.out.println();
            
            
    // 用私鑰解密
            String str1=rsaCoder.getDecryptString(encryptArray);
            System.out.println(
    "用私鑰解密后的字符串為:"+str1);
        }
    }

    輸出:
    準(zhǔn)備用公鑰加密的字符串為:你好,世界! Hello,world!
    用公鑰加密后的結(jié)果為:
    62-90-128-107-100-7070-11157-123-9160-6-116-68-1476-45-112-107-53-90107-84-670-9862-35-11116-83-10864312117-96-117-56995-2510321-89-89-828977-8810940100-91-76986562-222574-12815-120118-103-11-121-6030-6490-79-804911111-17-473984-7046-12294-8454-27108-26-11281-43833782-7926-612284-81781132357-3108-12673245-5111912-86-10041-799104-8146-5712374-55
    用私鑰解密后的字符串為:你好,世界! Hello,world
    !


    看到這里,如果有人說客戶端調(diào)用服務(wù)器端的getResponse函數(shù)時(shí),第一個(gè)參數(shù)params不是還會(huì)暴露一部分信息嗎? 不要怕,我們可以讓服務(wù)器端再準(zhǔn)備一個(gè)WebService函數(shù) byte[] getServerPublicKey();客戶端可以調(diào)用這個(gè)函數(shù)以得到服務(wù)器端的公鑰,然后把params用這個(gè)公鑰加密,然后再調(diào)用getResponse(String params,byte[] publicKeyArray)函數(shù),服務(wù)器端接到請(qǐng)求后,用自己的私鑰對(duì)第一個(gè)參數(shù)進(jìn)行解密就可以了。這樣,所有信息都得到了保護(hù)。

    如果String的表現(xiàn)力不夠怎么辦,有了XML的幫助,這從來不是問題,您說呢?

    好了,感謝您看到這里,希望上面的文字能對(duì)您有所幫助;如果您要使用的話,上面的代碼需要改寫一下,相信您知道該怎么辦。

    posted @ 2010-12-01 19:19 何楊 閱讀(499) | 評(píng)論 (0)編輯 收藏

    按:以下內(nèi)容涉及傳統(tǒng)的AES加密解密方法,熟悉它的請(qǐng)不要浪費(fèi)寶貴時(shí)間。

    如果用Base64進(jìn)行加密解密是不安全的,因?yàn)檫@種方式的方法和密鑰(字符映射表)都是公開的,對(duì)此熟悉的人如果看到一串字符后面帶一些等號(hào),很容易想到是Base64進(jìn)行加密。因此,我們必須采取一些更安全的加密解密方式,AES就是其一。

    在使用AES進(jìn)行加密解密之前,需要到Sun的官方網(wǎng)站上下載一個(gè)權(quán)限文件:jce_policy,目前它的下載網(wǎng)址是:http://www.oracle.com/technetwork/java/javase/downloads/index.html ,找到“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6”后點(diǎn)擊按鈕下載,得到下載文件后解開,然后將其中的local_policy.jar和US_export_policy.jar拷貝到你的JAVA_HOME\jre\lib\security和JRE_HOME\lib\security兩個(gè)目錄下。如果沒有這一步驟,進(jìn)行加密解密的時(shí)候會(huì)產(chǎn)生java.security.InvalidKeyException異常。

    接下來就是代碼了:
    package com.heyang.util;

    import java.security.Key;

    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;

    import org.apache.commons.codec.binary.Hex;


    /**
     * AES算法加密解密實(shí)用工具類
     * 說明:
     * 作者:何楊(heyang78@gmail.com)
     * 創(chuàng)建時(shí)間:2010-11-29 上午11:19:11
     * 修改時(shí)間:2010-11-29 上午11:19:11
     
    */
    public class AESSecurityUtil{
        
    // 加密方法
        private static final String Algorithm="AES";
        
        
    // 進(jìn)行加密解密的密鑰
        private static final String Key="03a53dfc257fe1b0996626a5e2e2210692936bd16cc60f37211cbeef9353e268";
        
        
    /**
         * 取得解密后的字符串
         * 
         * 說明:
         * 
    @param encryptArr
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-12-1 下午03:33:31
         
    */
        
    public static String getDecryptString(byte[] encryptArr){
            
    try{
                Cipher cp
    =Cipher.getInstance(Algorithm);
                cp.init(Cipher.DECRYPT_MODE, getKey());
                
    byte[] arr=cp.doFinal(encryptArr);
                
                
    return new String(arr);
            }
            
    catch(Exception ex){
                System.out.println(
    "無法進(jìn)行解密,原因是"+ex.getMessage());
                
    return null;
            }
        }
        
        
    /**
         * 取得加密后的字節(jié)數(shù)組
         * 
         * 說明:
         * 
    @param originalString
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-12-1 下午03:33:49
         
    */
        
    public static byte[] getEncryptByteArray(String originalString){
            
    try{
                Cipher cp
    =Cipher.getInstance(Algorithm);
                cp.init(Cipher.ENCRYPT_MODE, getKey());
                
    return cp.doFinal(originalString.getBytes());
            }
            
    catch(Exception ex){
                System.out.println(
    "無法進(jìn)行加密,原因是"+ex.getMessage());
                
    return null;
            }
        }
        
        
    /**
         * 取得密鑰數(shù)組
         * 
         * 說明:
         * 
    @return
         * 
    @throws Exception
         * 創(chuàng)建時(shí)間:2010-12-1 下午03:31:08
         
    */
        
    private static byte[] initKey() throws Exception{
            KeyGenerator kg
    =KeyGenerator.getInstance(Algorithm);
            kg.init(
    256);
            
            SecretKey sk
    =kg.generateKey();
            
            
    return sk.getEncoded();
        }
        
        
    /**
         * 取得字符串形式的密鑰
         * 
         * 說明:
         * 
    @return
         * 
    @throws Exception
         * 創(chuàng)建時(shí)間:2010-12-1 下午03:31:36
         
    */
        
    public static String initKeyHex() throws Exception{
            
    return new String(Hex.encodeHex(initKey()));
        }
        
        
    /**
         * 取得密鑰
         * 
         * 說明:
         * 
    @return
         * 
    @throws Exception
         * 創(chuàng)建時(shí)間:2010-12-1 下午03:33:17
         
    */
        
    private static Key getKey() throws Exception{
            
    byte[] arr=Hex.decodeHex(Key.toCharArray());
            
            
    return new SecretKeySpec(arr,Algorithm);
        }
        
        
    public static void main(String[] args)  throws Exception{
            
    //System.out.println(initKeyHex());
            
            String str
    ="Hello!World 你好!世界。";
            
            
    byte[] arr=AESSecurityUtil.getEncryptByteArray(str);
            System.out.print(
    "AES加密后的結(jié)果為:");
            
    for(byte b:arr){
                System.out.print(b);
            }
            System.out.println();
            
            String str1
    =AESSecurityUtil.getDecryptString(arr);
            System.out.println(
    "AES解密后的字符串為:"+str1);
        }
    }
    測(cè)試輸出如下:
    AES加密后的結(jié)果為:833522115-115-6373-10-940-110-93-87736-561-1083427-99-6-6218-4104108-1031216395-92
    AES解密后的字符串為:Hello
    !World 你好!世界。

    上面代碼中值得注意的是,加密后的結(jié)果不能直接變成String形式,因?yàn)檫@會(huì)導(dǎo)致解密的不可行(解密拋出javax.crypto.IllegalBlockSizeException異常)。如果要使用其他的Key,可以單獨(dú)執(zhí)行一下initKeyHex()函數(shù),將輸出結(jié)果置換掉靜態(tài)變量Key的值即可。

    這樣,在AES的幫助下,我們實(shí)現(xiàn)了比較安全的加密,破解者知道方法AES,但不知道密鑰的話,解密會(huì)很困難。但是,話說回來,java程序被反編譯很容易,別有用心的人還是可以看到密鑰,但我們還是可以用公鑰加密私鑰解密的方式來對(duì)付,這個(gè)以后有空再說。

    好了,感謝您看到這里。
    posted @ 2010-12-01 16:10 何楊 閱讀(4059) | 評(píng)論 (1)編輯 收藏

    按:以下內(nèi)容很簡(jiǎn)單,對(duì)Base64熟悉者無須往下看。

    Base64是一種基于64個(gè)字符的編碼算法,最早用于解決電子郵件傳輸?shù)膯栴},它的編碼和解碼操作可以充當(dāng)加密和解密操作,其字符映射表就是其密鑰。但是,Base64算法及其密鑰都是公開的,因此不能被認(rèn)為是安全的加密解密方法。

    下面是其示例代碼:
    package com.heyang.util;

    import org.apache.commons.codec.binary.Base64;


    /**
     * 常規(guī)Base64加密解密實(shí)用工具類
     * 說明:
     * 作者:何楊(heyang78@gmail.com)
     * 創(chuàng)建時(shí)間:2010-11-29 上午07:52:01
     * 修改時(shí)間:2010-11-29 上午07:52:01
     
    */
    public class Base64SecurityUtil{
        
    /**
         * 得到Base64加密后的字符串
         * 
         * 說明:
         * 
    @param originalString
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-11-29 上午07:53:30
         
    */
        
    public static String getEncryptString(String originalString){
            
    byte[] arr = Base64.encodeBase64(originalString.getBytes(), true);
            
    return new String(arr);
        }
        
        
    /**
         * 得到Base64解密后的字符串
         * 
         * 說明:
         * 
    @param encryptString
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-11-29 上午07:56:02
         
    */
        
    public static String getDecryptString(String encryptString){
            
    byte[] arr = Base64.decodeBase64(encryptString.getBytes());
            
    return new String(arr);
        }
        
        
    /**
         * 測(cè)試
         * 
         * 說明:
         * 
    @param args
         * 創(chuàng)建時(shí)間:2010-11-29 上午07:56:39
         
    */
        
    public static void main(String[] args){
            String str
    ="Hello world!你好,世界。";
            
            String str1
    =Base64SecurityUtil.getEncryptString(str);
            System.out.println(
    "經(jīng)Base64加密后的密文為"+str1);
            
            String str2
    =Base64SecurityUtil.getDecryptString(str1);
            System.out.println(
    "經(jīng)Base64解密后的原文為"+str2);
        }
    }
    輸出:
    經(jīng)Base64加密后的密文為SGVsbG8gd29ybGQhxOO6w6OsysC956Gj

    經(jīng)Base64解密后的原文為Hello world
    !你好,世界。


    posted @ 2010-11-29 08:10 何楊 閱讀(1242) | 評(píng)論 (0)編輯 收藏

    按:以下還是炒冷飯,如果您對(duì)加鹽了解就不用往下看了,以免浪費(fèi)寶貴時(shí)間。
    如果不了解下文部分細(xì)節(jié)的話,您可以參考這篇文章:使用MD5對(duì)存放在數(shù)據(jù)庫中用戶密碼進(jìn)行保護(hù)


    直接對(duì)重要數(shù)據(jù)進(jìn)行MD5處理后,反向解密確實(shí)難度很大,但還是可以找出破綻的,請(qǐng)看下圖:


    如果名為李自成的用戶可以查看數(shù)據(jù)庫,那么他可以觀察到自己的密碼和別人的密碼加密后的結(jié)果都是一樣,那么,別人用的和自己就是同一個(gè)密碼,這樣,就可以利用別人的身份登錄了。

    那么我們以前的加密方法是否對(duì)這種行為失效了呢?其實(shí)只要稍微混淆一下就能防范住了,這在加密術(shù)語中稱為“加鹽”。具體來說就是在原有材料(用戶自定義密碼)中加入其它成分(一般是用戶自有且不變的因素),以此來增加系統(tǒng)復(fù)雜度。當(dāng)這種鹽和用戶密碼相結(jié)合后,再通過摘要處理,就能得到隱蔽性更強(qiáng)的摘要值。下面請(qǐng)見代碼:
    // 對(duì)密碼進(jìn)行加鹽后加密,加密后再通過Hibernate往數(shù)據(jù)庫里存
            String changedPswd=DigestUtils.md5Hex(name+pswd);

    就是這樣簡(jiǎn)單,上面代碼中鹽就是用戶名,可以的話還可以用用戶注冊(cè)時(shí)的郵件,注冊(cè)時(shí)間等非空信息(如果是空信息這個(gè)加鹽處理會(huì)失效)。

    下面是數(shù)據(jù)庫中兩個(gè)用戶的記錄,他們的實(shí)際登錄密碼都是123456,但光看用戶記錄是完全看不出來的。這下別有用心的人打開數(shù)據(jù)庫看到的密碼都完全不一樣,他以前的手段就失效了。


    加鹽就是這樣簡(jiǎn)單,感謝您看到這里。




    posted @ 2010-11-28 09:53 何楊 閱讀(11808) | 評(píng)論 (6)編輯 收藏

    以下文章屬于老調(diào)重彈,您如果對(duì)MD5的使用已經(jīng)熟悉請(qǐng)不要往下看以免浪費(fèi)寶貴時(shí)間。

    登錄Web系統(tǒng)時(shí)通常都采用用戶名和密碼的形式,如果這樣的數(shù)據(jù)以明碼的方式放在數(shù)據(jù)庫中的話無疑會(huì)給別有用心的人以可趁之機(jī),所以采取一定的防范措施是必要的。

    現(xiàn)在比較安全的方式是用MD5進(jìn)行加密,利用Apache commons的DigestUtils工具類我們可以迅速做到這一點(diǎn)。
    要得到Apache commons的DigestUtils工具類,你必須加載commons-codec-1.x.jar包,我使用的是commons-codec-1.3.jar。使用的具體類是:org.apache.commons.codec.digest.DigestUtils.

    下面,我們的任務(wù)是,當(dāng)用戶注冊(cè)時(shí),將他注冊(cè)的密碼加密后存入數(shù)據(jù)庫,下面請(qǐng)見具體代碼:
     1 // 對(duì)密碼進(jìn)行加密,加密后再通過Hibernate往數(shù)據(jù)庫里存
     2         String changedPswd=DigestUtils.md5Hex(pswd);
     3         
     4         User user=new User(name,changedPswd,email,brief);
     5         
     6         if(service.hasSameName(name)){
     7             // 同名檢測(cè)
     8             request.setAttribute("msg""已經(jīng)有和'"+name+"'同名的用戶存在了,請(qǐng)換個(gè)名稱注冊(cè).");
     9             return new ActionForward("/web/page/register.jsp");
    10         }
    11         
    12         if(service.hasSameEmail(email)){
    13             // 同Emial檢測(cè)
    14             request.setAttribute("msg""已經(jīng)有和'"+email+"'相同的用戶存在了,請(qǐng)換個(gè)Email注冊(cè).");
    15             return new ActionForward("/web/page/register.jsp");
    16         }
    17         
    18         try{
    19             service.create(user);
    20             saveUserRegisterInforToLog(user,request);
    21             request.setAttribute("msg"""+name+",歡迎您的加盟.???????¼???");
    22             return new ActionForward("/web/page/login.jsp");
    23         }
    24         catch(Exception ex){
    25             String str="創(chuàng)建用戶時(shí)遇到未預(yù)計(jì)的異常,具體的異常信息為'"+ex.getMessage()+"',請(qǐng)與系統(tǒng)維護(hù)人員聯(lián)系.";
    26             request.setAttribute("msg",str );
    27             logger.fatal(str);
    28             return new ActionForward("/web/page/register.jsp");
    29         }

    以上第二行代碼是進(jìn)行MD5加密的處理,如果用戶輸入的密碼是123456789,則會(huì)得到25f9e794323b453885f5181f1b624d0b這樣的字符串。

    注冊(cè)用戶后,數(shù)據(jù)庫中您將看到如下的對(duì)應(yīng)記錄,看到這樣的文字,要去反猜原始密碼是非常困難的,當(dāng)然您有山東大學(xué)王小云教授的本事則不費(fèi)吹灰之力。


    下面,我們還要對(duì)登錄時(shí)做一番處理,因?yàn)榈卿洉r(shí)用的是原始密碼,我們應(yīng)該對(duì)它進(jìn)行加密后再和數(shù)據(jù)庫中的對(duì)應(yīng)字段進(jìn)行比對(duì),代碼如下:
                User user=objs.get(0);
                
                
    // 得到MD5加密后的密碼
                String changedPswd=DigestUtils.md5Hex(password);
                    
                
    // 再與數(shù)據(jù)庫中用戶密碼進(jìn)行比對(duì)
                if(user.getPassword().equals(changedPswd)==false){
                    
    throw new ErrorPswdException("密碼不匹配.");
                }
    else{
                    
    return user;


                }

    以上代碼中,password是用戶在頁面輸入的原始密碼,changedPswd是經(jīng)過MD5加密后的密碼,user是按名稱查詢出來的用戶,他的密碼部分就是已經(jīng)經(jīng)過MD5加密的,我們拿這兩個(gè)密碼進(jìn)行比對(duì)即可。

    之所以沒有反向還原是因?yàn)镸D5加密和Base64不一樣,前者是不可逆的,后者則可以還原。當(dāng)然,Base64不是嚴(yán)格意義上的加密手段。

    最后的問題,如果數(shù)據(jù)庫中原有數(shù)據(jù)未經(jīng)加密怎么辦,好在MySql數(shù)據(jù)庫提供了md5函數(shù)幫我們做到這一點(diǎn),使用update projectmanager_user set pswd=md5(pswd) 這樣的語句就可以將原來數(shù)據(jù)庫中的密碼部分用MD5加密了。

    下面的圖片演示了這一過程:

    原始數(shù)據(jù):


    使用update projectmanager_user set pswd=md5(pswd)加密后的數(shù)據(jù)庫記錄:


    到此啰嗦完了,感謝您看到這里。
    posted @ 2010-11-27 13:56 何楊 閱讀(7916) | 評(píng)論 (4)編輯 收藏

    僅列出標(biāo)題
    共28頁: First 上一頁 14 15 16 17 18 19 20 21 22 下一頁 Last 
    主站蜘蛛池模板: 国产精品美女免费视频观看| 一级a性色生活片久久无少妇一级婬片免费放 | 亚洲综合激情九月婷婷| 亚洲AV无码男人的天堂| 国产三级在线免费| 午夜毛片不卡高清免费| 亚洲女同成av人片在线观看| 国产.亚洲.欧洲在线| 巨胸喷奶水www永久免费| 久久综合AV免费观看| 亚洲精品乱码久久久久久蜜桃不卡 | 99re热免费精品视频观看| 亚洲AV中文无码乱人伦| 亚洲黄色高清视频| 男女猛烈激情xx00免费视频| 人与禽交免费网站视频| 亚洲午夜无码久久久久| 亚洲精品无码专区| 久久成人无码国产免费播放| 国产免费131美女视频| 亚洲天堂福利视频| 国内永久免费crm系统z在线 | 亚洲不卡在线观看| 九九视频高清视频免费观看 | 美女被cao免费看在线看网站| 在线亚洲午夜理论AV大片| 亚洲色偷偷色噜噜狠狠99网| 一级毛片免费观看| 中文字幕第13亚洲另类| 亚洲国产成人AV网站| 99久久久国产精品免费无卡顿 | 久久精品亚洲日本波多野结衣 | 久久精品国产亚洲AV不卡| 亚洲高清一区二区三区电影| 91香蕉国产线在线观看免费| 亚洲中文无韩国r级电影| 亚洲成av人片天堂网无码】| 免费观看黄色的网站| 亚洲第一精品在线视频| 精品一区二区三区免费视频| 国产hs免费高清在线观看|