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

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

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

    每日一得

    不求多得,只求一得 about java,hibernate,spring,design,database,Ror,ruby,快速開發
    最近關心的內容:SSH,seam,flex,敏捷,TDD
    本站的官方站點是:顛覆軟件

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      220 隨筆 :: 9 文章 :: 421 評論 :: 0 Trackbacks
    本文主要談一下密碼學中的加密和數字簽名,以及其在java中如何進行使用。對密碼學有興趣的伙伴,推薦看 Bruce Schneier的著作:Applied Crypotography。在jdk1.5的發行版本中安全性方面有了很大的改進,也提供了對RSA算法的直接支持,現在我們從實例入手解決問題(本文 僅是作為簡單介紹):

      一、密碼學上常用的概念 

      1)消息摘要:

       這是一種與消息認證碼結合使用以確保消息完整性的技術。主要使用單向散列函數算法,可用于檢驗消息的完整性,和通過散列密碼直接以文本形式保存等,目前 廣泛使用的算法有MD4、MD5、SHA-1,jdk1.5對上面都提供了支持,在java中進行消息摘要很簡單, java.security.MessageDigest提供了一個簡易的操作方法:

    /**
    *MessageDigestExample.java
    *Copyright?2005-2-16
    */
    import?java.security.MessageDigest;
    /**
    *單一的消息摘要算法,不使用密碼.可以用來對明文消息(如:密碼)隱藏保存
    */
    public?class?MessageDigestExample{
     
    public?static?void?main(String[]?args)?throws?Exception{
      
    if(args.length!=1){
       System.err.println(
    "Usage:java?MessageDigestExample?text");
       System.exit(
    1);
      }

      
    byte[]?plainText=args[0].getBytes("UTF8");

      
    //使用getInstance("算法")來獲得消息摘要,這里使用SHA-1的160位算法
      MessageDigest?messageDigest=MessageDigest.getInstance("SHA-1");

      System.out.println(
    "\n"+messageDigest.getProvider().getInfo());
      
    //開始使用算法
      messageDigest.update(plainText);
      System.out.println(
    "\nDigest:");
      
    //輸出算法運算結果
      System.out.println(new?String(messageDigest.digest(),"UTF8"));
     }
    }

      還可以通過消息認證碼來進行加密實現,javax.crypto.Mac提供了一個解決方案,有興趣者可以參考相關API文檔,本文只是簡單介紹什么是摘要算法。

    這里補充另一個運用消息摘要的方式加密的例子:
    public?class?TestEncrypt?{

    ????
    public?TestEncrypt()?{
    ????}

    ????
    /**
    ?????*?
    @param?strSrc??:strSrc?is?a?string?will?be?encrypted,
    ?????*?
    @param?encName?:?encName?is?the?algorithm?name?will?be?used.
    ?????*????????????????encName?dafault?to?"MD5"
    ?????*?
    @return?String
    ?????
    */
    ????
    public?String?Encrypt(String?strSrc,?String?encName)?{

    ????????MessageDigest?md?
    =?null;
    ????????String?strDes?
    =?null;

    ????????
    byte[]?bt?=?strSrc.getBytes();
    ????????
    try?{
    ????????????
    if?(encName?==?null?||?encName.equals(""))?{
    ????????????????encName?
    =?"MD5";
    ????????????}
    ????????????md?
    =?MessageDigest.getInstance(encName);
    ????????????md.update(bt);
    ????????????strDes?
    =?bytes2Hex(md.digest());?//to?HexString
    ????????}
    ????????
    catch?(NoSuchAlgorithmException?e)?{
    ????????????System.out.println(
    "Invalid?algorithm.");
    ????????????
    return?null;
    ????????}
    ????????
    return?strDes;
    ????}

    ????
    public?String?bytes2Hex(byte[]?bts)?{
    ????????String?des?
    =?"";
    ????????String?tmp?
    =?null;
    ????????
    for?(int?i?=?0;?i?<?bts.length;?i++)?{
    ????????????tmp?
    =?(Integer.toHexString(bts[i]?&?0xFF));
    ????????????
    if?(tmp.length()?==?1)?{
    ????????????????des?
    +=?"0";
    ????????????}
    ????????????des?
    +=?tmp;
    ????????}
    ????????
    return?des;
    ????}

    ????
    public?static?void?main(String[]args)?{
    ????????TestEncrypt?te?
    =?new?TestEncrypt();
    ????????String?strSrc?
    =?"可以加密漢字.Oh,and?english";
    ????????System.out.println(
    "Source?String:"?+?strSrc);
    ????????System.out.println(
    "Encrypted?String:");
    ????????System.out.println(
    "Use?Def:"?+?te.Encrypt(strSrc,?null));
    ????????System.out.println(
    "Use?MD5:"?+?te.Encrypt(strSrc,?"MD5"));
    ????????System.out.println(
    "Use?SHA:"?+?te.Encrypt(strSrc,?"SHA-1"));
    ????????System.out.println(
    "Use?SHA-256:"?+?te.Encrypt(strSrc,?"SHA-256"));
    ????}
    }

    另外,在javawebparts中的 RequestHelpers里的generateGUID方法也涉及到了MD5的方法,代碼如下:
    public?static?String?generateGUID(HttpServletRequest?request)?{

    ????String?out?
    =?"";
    ????
    try?{
    ??????
    //?Construct?a?string?that?is?comprised?of:
    ??????
    //?Remote?IP?Address?+?Host?IP?Address?+?Date?(yyyyMMdd)?+
    ??????
    //?Time?(hhmmssSSa)?+?Requested?Path?+?Session?ID?+
    ??????
    //?HashCode?Of?ParameterMap
    ??????StringBuffer?sb?=?new?StringBuffer(1024);
    ??????sb.append(request.getRemoteAddr());
    ??????InetAddress?ia?
    =?InetAddress.getLocalHost();
    ??????sb.append(ia.getHostAddress());
    ??????sb.append(
    new?SimpleDateFormat("yyyyMMddhhmmssSSa").format(new?Date()));
    ??????String?path?
    =?request.getServletPath();
    ??????String?pathInfo?
    =?request.getPathInfo();
    ??????
    if?(pathInfo?!=?null)?{
    ????????path?
    +=?pathInfo;
    ??????}
    ??????sb.append(path);
    ??????sb.append(request.getSession(
    false));
    ??????sb.append(request.getParameterMap().hashCode());
    ??????String?str?
    =?sb.toString();
    ??????
    //?Now?encode?the?string?using?an?MD5?encryption?algorithm.
    ??????MessageDigest?md?=?MessageDigest.getInstance("md5");
    ??????md.update(str.getBytes());
    ??????
    byte[]?digest?=?md.digest();
    ??????StringBuffer?hexStr?
    =?new?StringBuffer(1024);
    ??????
    for?(int?i?=?0;?i?<?digest.length;?i++)?{
    ????????str?
    =?Integer.toHexString(0xFF?&?digest[i]);
    ????????
    if?(str.length()?<?2)?{
    ??????????str?
    =?"0"?+?str;
    ????????}
    ????????hexStr.append(str);
    ??????}
    ??????out?
    =?hexStr.toString();
    ????}?
    catch?(NoSuchAlgorithmException?nsae)?{
    ??????log.error(nsae);
    ????}?
    catch?(UnknownHostException?uhe)?{
    ??????log.error(uhe);
    ????}
    ????
    //?Return?the?encrypted?string.??It?should?be?unique?based?on?the
    ????
    //?components?that?comprise?the?plain?text?string,?and?should?always?be
    ????
    //?32?characters?thanks?to?the?MD5?algorithm.
    ????return?out;

    ??}?
    //?End?generateGUID().


      2)私鑰加密:

      消息摘要只能檢查消息的完整性,但是單向的,對明文消息并不能加密,要加密明文的消息的話,就要使用其他的算法,要確保機密性,我們需要使用私鑰密碼術來交換私有消息。

      這種最好理解,使用對稱算法。比如:A用一個密鑰對一個文件加密,而B讀取這個文件的話,則需要和A一樣的密鑰,雙方共享一個私鑰(而在web環境下,私鑰在傳遞時容易被偵聽):

       使用私鑰加密的話,首先需要一個密鑰,可用javax.crypto.KeyGenerator產生一個密鑰(java.security.Key), 然后傳遞給一個加密工具(javax.crypto.Cipher),該工具再使用相應的算法來進行加密,主要對稱算法有:DES(實際密鑰只用到56 位),AES(支持三種密鑰長度:128、192、256位),通常首先128位,其他的還有DESede等,jdk1.5種也提供了對對稱算法的支持, 以下例子使用AES算法來加密:

    /**
    *PrivateExmaple.java
    *Copyright?2005-2-16
    */
    import?javax.crypto.Cipher;
    import?javax.crypto.KeyGenerator;
    import?java.security.Key;

    /**
    *私鈅加密,保證消息機密性
    */
    public?class?PrivateExample{
     
    public?static?void?main(String[]?args)?throws?Exception{
      
    if(args.length!=1){
       System.err.println(
    "Usage:java?PrivateExample?<text>");
       System.exit(
    1);
      }
      
    byte[]?plainText=args[0].getBytes("UTF8");

      
    //通過KeyGenerator形成一個key
      System.out.println("\nStart?generate?AES?key");
      KeyGenerator?keyGen
    =KeyGenerator.getInstance("AES");
      keyGen.init(
    128);
      Key?key
    =keyGen.generateKey();
      System.out.println(
    "Finish?generating?DES?key");

      
    //獲得一個私鈅加密類Cipher,ECB是加密方式,PKCS5Padding是填充方法
      Cipher?cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
      System.out.println(
    "\n"+cipher.getProvider().getInfo());

      
    //使用私鈅加密
      System.out.println("\nStart?encryption:");
      cipher.init(Cipher.ENCRYPT_MODE,key);
      
    byte[]?cipherText=cipher.doFinal(plainText);
      System.out.println(
    "Finish?encryption:");
      System.out.println(
    new?String(cipherText,"UTF8"));

      System.out.println(
    "\nStart?decryption:");
      cipher.init(Cipher.DECRYPT_MODE,key);
      
    byte[]?newPlainText=cipher.doFinal(cipherText);
      System.out.println(
    "Finish?decryption:");

      System.out.println(
    new?String(newPlainText,"UTF8"));

     }
    }

      3)公鑰加密:

       上面提到,私鑰加密需要一個共享的密鑰,那么如何傳遞密鑰呢?web環境下,直接傳遞的話很容易被偵聽到,幸好有了公鑰加密的出現。公鑰加密也叫不對稱 加密,不對稱算法使用一對密鑰對,一個公鑰,一個私鑰,使用公鑰加密的數據,只有私鑰能解開(可用于加密);同時,使用私鑰加密的數據,只有公鑰能解開 (簽名)。但是速度很慢(比私鑰加密慢100到1000倍),公鑰的主要算法有RSA,還包括Blowfish,Diffie-Helman等, jdk1.5種提供了對RSA的支持,是一個改進的地方:

    /**
    *PublicExample.java
    *Copyright?2005-2-16
    */
    import?java.security.Key;
    import?javax.crypto.Cipher;
    import?java.security.KeyPairGenerator;
    import?java.security.KeyPair;
    /**
    *一個簡單的公鈅加密例子,Cipher類使用KeyPairGenerator生成的公鈅和私鈅
    */
    public?class?PublicExample{
     
    public?static?void?main(String[]?args)?throws?Exception{
      
    if(args.length!=1){
       System.err.println(
    "Usage:java?PublicExample?<text>");
       System.exit(
    1);
      }

      
    byte[]?plainText=args[0].getBytes("UTF8");
      
    //構成一個RSA密鑰
      System.out.println("\nStart?generating?RSA?key");
      KeyPairGenerator?keyGen
    =KeyPairGenerator.getInstance("RSA");
      keyGen.initialize(
    1024);
      KeyPair?key
    =keyGen.generateKeyPair();
      System.out.println(
    "Finish?generating?RSA?key");

      
    //獲得一個RSA的Cipher類,使用公鈅加密
      Cipher?cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
      System.out.println(
    "\n"+cipher.getProvider().getInfo());

      System.out.println(
    "\nStart?encryption");
      cipher.init(Cipher.ENCRYPT_MODE,key.getPublic());
      
    byte[]?cipherText=cipher.doFinal(plainText);
      System.out.println(
    "Finish?encryption:");
      System.out.println(
    new?String(cipherText,"UTF8"));

      
    //使用私鈅解密
      System.out.println("\nStart?decryption");
      cipher.init(Cipher.DECRYPT_MODE,key.getPrivate());
      
    byte[]?newPlainText=cipher.doFinal(cipherText);
      System.out.println(
    "Finish?decryption:");
      System.out.println(
    new?String(newPlainText,"UTF8"));
     }
    }

    posted on 2006-09-07 23:59 Alex 閱讀(1161) 評論(0)  編輯  收藏 所屬分類: 加密解密

    只有注冊用戶登錄后才能發表評論。


    網站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 免费国产在线观看| 四虎永久在线精品免费一区二区 | 久久亚洲精品无码gv| 亚洲欭美日韩颜射在线二| 成人毛片免费播放| 91成人免费观看| 免费一级毛片在线播放视频免费观看永久 | 91成人免费观看在线观看| 亚洲一区二区三区播放在线| 亚洲日韩欧洲无码av夜夜摸| 亚洲av无码不卡私人影院| A级毛片内射免费视频| 99视频免费播放| 国产成人AV免费观看| 精品免费久久久久国产一区 | 日本免费精品一区二区三区| 91在线亚洲综合在线| 亚洲国产精品yw在线观看| 亚洲欧洲日韩不卡| 亚洲人成无码网站| 亚洲日韩欧洲乱码AV夜夜摸| 亚洲女同成人AⅤ人片在线观看 | 亚洲视频精品在线| 亚洲国产成人片在线观看| 久99精品视频在线观看婷亚洲片国产一区一级在线 | 久久免费99精品国产自在现线| 国产偷v国产偷v亚洲高清| 国产91精品一区二区麻豆亚洲| 免费国产污网站在线观看15| 国产无遮挡裸体免费视频在线观看 | 国产成人精品日本亚洲专区61 | 亚洲综合一区二区国产精品| 亚洲av无码精品网站| 久久久青草青青亚洲国产免观 | 97se亚洲国产综合自在线| 亚洲av午夜精品无码专区| 亚洲国产精品线观看不卡| 亚洲第一页中文字幕| 2020久久精品亚洲热综合一本| 亚洲精品乱码久久久久久| 国产A在亚洲线播放|