熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java加密和數字簽名

2013-11-23 19:27:27  來源: Java核心技術 

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

  一密碼學上常用的概念 

  )消息摘要

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

  /**
    *MessageDigestExamplejava
    *Copyright
    */
    import javasecurityMessageDigest;
    /**
    *單一的消息摘要算法不使用密碼可以用來對明文消息(如密碼)隱藏保存
    */
    public class MessageDigestExample{
     public static void main(String[] args) throws Exception{
      if(argslength!=){
       Systemerrprintln(Usage:java MessageDigestExample text);
       Systemexit();
      }

  byte[] plainText=args[]getBytes(UTF);

  //使用getInstance(算法)來獲得消息摘要這裡使用SHA位算法
      MessageDigest messageDigest=MessageDigestgetInstance(SHA);

  Systemoutprintln(\n+messageDigestgetProvider()getInfo());
      //開始使用算法
      messageDigestupdate(plainText);
      Systemoutprintln(\nDigest:);
      //輸出算法運算結果
      Systemoutprintln(new String(messageDigestdigest()UTF));
     }
    }
    還可以通過消息認證碼來進行加密實現javaxcryptoMac提供了一個解決方案有興趣者可以參考相關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 MD
         * @return String
         */
        public String Encrypt(String strSrc String encName) {

  MessageDigest md = null;
            String strDes = null;

  byte[] bt = strSrcgetBytes();
            try {
                if (encName == null || encNameequals()) {
                    encName = MD;
                }
                md = MessageDigestgetInstance(encName);
                mdupdate(bt);
                strDes = bytesHex(mddigest()); //to HexString
            }
            catch (NoSuchAlgorithmException e) {
                Systemoutprintln(Invalid algorithm);
                return null;
            }
            return strDes;
        }

  public String bytesHex(byte[] bts) {
            String des = ;
            String tmp = null;
            for (int i = ; i < btslength; i++) {
                tmp = (IntegertoHexString(bts[i] & xFF));
                if (tmplength() == ) {
                    des += ;
                }
                des += tmp;
            }
            return des;
        }

  public static void main(String[]args) {
            TestEncrypt te = new TestEncrypt();
            String strSrc = 可以加密漢字Ohand english;
            Systemoutprintln(Source String: + strSrc);
            Systemoutprintln(Encrypted String:);
            Systemoutprintln(Use Def: + teEncrypt(strSrc null));
            Systemoutprintln(Use MD: + teEncrypt(strSrc MD));
            Systemoutprintln(Use SHA: + teEncrypt(strSrc SHA));
            Systemoutprintln(Use SHA: + teEncrypt(strSrc SHA));
        }
    }

  另外在javawebparts中的 RequestHelpers裡的generateGUID方法也涉及到了MD的方法代碼如下:
    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();
          sbappend(requestgetRemoteAddr());
          InetAddress ia = InetAddressgetLocalHost();
          sbappend(iagetHostAddress());
          sbappend(new SimpleDateFormat(yyyyMMddhhmmssSSa)format(new Date()));
          String path = requestgetServletPath();
          String pathInfo = requestgetPathInfo();
          if (pathInfo != null) {
            path += pathInfo;
          }
          sbappend(path);
          sbappend(requestgetSession(false));
          sbappend(requestgetParameterMap()hashCode());
          String str = sbtoString();
          // Now encode the string using an MD encryption algorithm
          MessageDigest md = MessageDigestgetInstance(md);
          mdupdate(strgetBytes());
          byte[] digest = mddigest();
          StringBuffer hexStr = new StringBuffer();
          for (int i = ; i < digestlength; i++) {
            str = IntegertoHexString(xFF & digest[i]);
            if (strlength() < ) {
              str = + str;
            }
            hexStrappend(str);
          }
          out = hexStrtoString();
        } catch (NoSuchAlgorithmException nsae) {
          logerror(nsae);
        } catch (UnknownHostException uhe) {
          logerror(uhe);
        }
        // Return the encrypted string It should be unique based on the
        // components that comprise the plain text string and should always be
        // characters thanks to the MD algorithm
        return out;

  } // End generateGUID()

  )私鑰加密

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

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

  使用私鑰加密的話首先需要一個密鑰可用javaxcryptoKeyGenerator產生一個密鑰(javasecurityKey) 然後傳遞給一個加密工具(javaxcryptoCipher)該工具再使用相應的算法來進行加密主要對稱算法有DES(實際密鑰只用到 位)AES(支持三種密鑰長度位)通常首先其他的還有DESede等jdk種也提供了對對稱算法的支持以下例子使用AES算法來加密

  /**
    *PrivateExmaplejava
    *Copyright
    */
    import javaxcryptoCipher;
    import javaxcryptoKeyGenerator;
    import javasecurityKey;

  /**
    *私鈅加密保證消息機密性
    */
    public class PrivateExample{
     public static void main(String[] args) throws Exception{
      if(argslength!=){
       Systemerrprintln(Usage:java PrivateExample <text>);
       Systemexit();
      }
      byte[] plainText=args[]getBytes(UTF);

  //通過KeyGenerator形成一個key
      Systemoutprintln(\nStart generate AES key);
      KeyGenerator keyGen=KeyGeneratorgetInstance(AES);
      keyGeninit();
      Key key=keyGengenerateKey();
      Systemoutprintln(Finish generating DES key);

  //獲得一個私鈅加密類CipherECB是加密方式PKCSPadding是填充方法
      Cipher cipher=CiphergetInstance(AES/ECB/PKCSPadding);
      Systemoutprintln(\n+ciphergetProvider()getInfo());

  //使用私鈅加密
      Systemoutprintln(\nStart encryption:);
      cipherinit(CipherENCRYPT_MODEkey);
      byte[] cipherText=cipherdoFinal(plainText);
      Systemoutprintln(Finish encryption:);
      Systemoutprintln(new String(cipherTextUTF));

  Systemoutprintln(\nStart decryption:);
      cipherinit(CipherDECRYPT_MODEkey);
      byte[] newPlainText=cipherdoFinal(cipherText);
      Systemoutprintln(Finish decryption:);

  Systemoutprintln(new String(newPlainTextUTF));

  }
    }

  )公鑰加密

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

  /**
    *PublicExamplejava
    *Copyright
    */
    import javasecurityKey;
    import javaxcryptoCipher;
    import javasecurityKeyPairGenerator;
    import javasecurityKeyPair;
    /**
    *一個簡單的公鈅加密例子Cipher類使用KeyPairGenerator生成的公鈅和私鈅
    */
    public class PublicExample{
     public static void main(String[] args) throws Exception{
      if(argslength!=){
       Systemerrprintln(Usage:java PublicExample <text>);
       Systemexit();
      }

  byte[] plainText=args[]getBytes(UTF);
      //構成一個RSA密鑰
      Systemoutprintln(\nStart generating RSA key);
      KeyPairGenerator keyGen=KeyPairGeneratorgetInstance(RSA);
      keyGeninitialize();
      KeyPair key=keyGengenerateKeyPair();
      Systemoutprintln(Finish generating RSA key);

  //獲得一個RSA的Cipher類使用公鈅加密
      Cipher cipher=CiphergetInstance(RSA/ECB/PKCSPadding);
      Systemoutprintln(\n+ciphergetProvider()getInfo());

  Systemoutprintln(\nStart encryption);
      cipherinit(CipherENCRYPT_MODEkeygetPublic());
      byte[] cipherText=cipherdoFinal(plainText);
      Systemoutprintln(Finish encryption:);
      Systemoutprintln(new String(cipherTextUTF));

  //使用私鈅解密
      Systemoutprintln(\nStart decryption);
      cipherinit(CipherDECRYPT_MODEkeygetPrivate());
      byte[] newPlainText=cipherdoFinal(cipherText);
      Systemoutprintln(Finish decryption:);
      Systemoutprintln(new String(newPlainTextUTF));
     }
    }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26898.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.