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

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

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

    風(fēng)人園

    弱水三千,只取一瓢,便能解渴;佛法無邊,奉行一法,便能得益。
    隨筆 - 99, 文章 - 181, 評論 - 56, 引用 - 0
    數(shù)據(jù)加載中……

    Java加密和數(shù)字簽名

    本文主要談一下密碼學(xué)中的加密和數(shù)字簽名,以及其在java中如何進(jìn)行使用。對密碼學(xué)有興趣的伙伴,推薦看 Bruce Schneier的著作:Applied Crypotography。在jdk1.5的發(fā)行版本中安全性方面有了很大的改進(jìn),也提供了對RSA算法的直接支持,現(xiàn)在我們從實例入手解決問題(本文僅是作為簡單介紹):

      一、密碼學(xué)上常用的概念 

      1)消息摘要:

      這是一種與消息認(rèn)證碼結(jié)合使用以確保消息完整性的技術(shù)。主要使用單向散列函數(shù)算法,可用于檢驗消息的完整性,和通過散列密碼直接以文本形式保存等,目前廣泛使用的算法有MD4、MD5、SHA-1,jdk1.5對上面都提供了支持,在java中進(jìn)行消息摘要很簡單, 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:");
      
    //輸出算法運算結(jié)果
      System.out.println(new?String(messageDigest.digest(),"UTF8"));
     }
    }

      還可以通過消息認(rèn)證碼來進(jìn)行加密實現(xiàn),javax.crypto.Mac提供了一個解決方案,有興趣者可以參考相關(guān)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)私鑰加密:

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

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

      使用私鑰加密的話,首先需要一個密鑰,可用javax.crypto.KeyGenerator產(chǎn)生一個密鑰(java.security.Key), 然后傳遞給一個加密工具(javax.crypto.Cipher),該工具再使用相應(yīng)的算法來進(jìn)行加密,主要對稱算法有: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環(huán)境下,直接傳遞的話很容易被偵聽到,幸好有了公鑰加密的出現(xiàn)。公鑰加密也叫不對稱加密,不對稱算法使用一對密鑰對,一個公鑰,一個私鑰,使用公鑰加密的數(shù)據(jù),只有私鑰能解開(可用于加密);同時,使用私鑰加密的數(shù)據(jù),只有公鑰能解開(簽名)。但是速度很慢(比私鑰加密慢100到1000倍),公鑰的主要算法有RSA,還包括Blowfish,Diffie-Helman等, jdk1.5種提供了對RSA的支持,是一個改進(jìn)的地方:

    /**
    *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");
      
    //構(gòu)成一個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-11-01 14:07 風(fēng)人園 閱讀(332) 評論(0)  編輯  收藏 所屬分類: 算法

    主站蜘蛛池模板: 国产精品偷伦视频免费观看了| 亚洲人成网站色在线入口| 18国产精品白浆在线观看免费| 无码欧精品亚洲日韩一区夜夜嗨| 亚洲午夜理论片在线观看| 91青青国产在线观看免费| 亚洲区小说区图片区QVOD| 一级做a爰全过程免费视频毛片| 国产成人精品男人免费| 亚洲人成电影网站色| 免费高清资源黄网站在线观看 | 亚洲精品欧洲精品| 日韩免费观看一区| 亚洲精品国产精品乱码在线观看| 精品久久久久久国产免费了| 久久久久噜噜噜亚洲熟女综合| 一级一黄在线观看视频免费| 亚洲第一页中文字幕| 久久久久亚洲AV综合波多野结衣| 99久久免费国产香蕉麻豆| eeuss免费天堂影院| 亚洲视频在线观看2018| 91青青国产在线观看免费 | 在线看片韩国免费人成视频| 一个人免费观看视频在线中文| 亚洲天堂一区在线| 成人黄动漫画免费网站视频| 亚洲精品无播放器在线播放 | 亚洲AV之男人的天堂| 羞羞视频免费网站在线看| 亚洲午夜精品久久久久久app| 亚洲国产精品久久久久婷婷老年| 8888四色奇米在线观看免费看| 成人免费视频一区二区| 亚洲成AV人片在WWW色猫咪| 久久国产高潮流白浆免费观看| 一级毛片**免费看试看20分钟 | 亚洲一级免费视频| 亚洲va中文字幕| 亚洲人成影院77777| 亚洲AV无码专区日韩|