天天看點

加密算法、DES、IDEA、RSA、DSA

轉載于 http://desert3.iteye.com/blog/743713

加密技術是對資訊進行編碼和解碼的技術,編碼是把原來可讀資訊(又稱明文)譯成代碼形式(又稱密文),其逆過程就是解碼(解密)。加密技術的要點是加密算法,加密算法可以分為對稱加密、不對稱加密和不可逆加密三類算法。 

對稱加密算法:對稱加密算法是應用較早的加密算法,技術成熟。在對稱加密算法中,資料發信方将明文(原始資料)和加密密鑰一起經過特殊加密算法處理後,使其變成複雜的加密密文發送出去。收信方收到密文後,若想解讀原文,則需要使用加密用過的密鑰及相同算法的逆算法對密文進行解密,才能使其恢複成可讀明文。在對稱加密算法中,使用的密鑰隻有一個,發收信雙方都使用這個密鑰對資料進行加密和解密,這就要求解密方事先必須知道加密密鑰。對稱加密算法的特點是算法公開、計算量小、加密速度快、加密效率高。不足之處是,交易雙方都使用同樣鑰匙,安全性得不到保證。此外,每對使用者每次使用對稱加密算法時,都需要使用其他人不知道的惟一鑰匙,這會使得發收信雙方所擁有的鑰匙數量成幾何級數增長,密鑰管理成為使用者的負擔。對稱加密算法在分布式網絡系統上使用較為困難,主要是因為密鑰管理困難,使用成本較高。在計算機專網系統中廣泛使用的對稱加密算法有DES(Data Encryption Standard)和IDEA等。美國國家标準局倡導的AES即将作為新标準取代DES。 

不對稱加密算法:不對稱加密算法使用兩把完全不同但又是完全比對的一對鑰匙—公鑰和私鑰。在使用不對稱加密算法加密檔案時,隻有使用比對的一對公鑰和私鑰,才能完成對明文的加密和解密過程。加密明文時采用公鑰加密,解密密文時使用私鑰才能完成,而且發信方(加密者)知道收信方的公鑰,隻有收信方(解密者)才是唯一知道自己私鑰的人。不對稱加密算法的基本原理是,如果發信方想發送隻有收信方才能解讀的加密資訊,發信方必須首先知道收信方的公鑰,然後利用收信方的公鑰來加密原文;收信方收到加密密文後,使用自己的私鑰才能解密密文。顯然,采用不對稱加密算法,收發信雙方在通信之前,收信方必須将自己早已随機生成的公鑰送給發信方,而自己保留私鑰。由于不對稱算法擁有兩個密鑰,因而特别适用于分布式系統中的資料加密。廣泛應用的不對稱加密算法有RSA算法和美國國家标準局提出的DSA(Digital Signature Algorithm)。以不對稱加密算法為基礎的加密技術應用非常廣泛。 

不可逆加密算法:不可逆加密算法的特征是加密過程中不需要使用密鑰,輸入明文後由系統直接經過加密算法處理成密文,這種加密後的資料是無法被解密的,隻有重新輸入明文,并再次經過同樣不可逆的加密算法處理,得到相同的加密密文并被系統重新識别後,才能真正解密。顯然,在這類加密過程中,加密是自己,解密還得是自己,而所謂解密,實際上就是重新加一次密,所應用的“密碼”也就是輸入的明文。不可逆加密算法不存在密鑰保管和分發問題,非常适合在分布式網絡系統上使用,但因加密計算複雜,工作量相當繁重,通常隻在資料量有限的情形下使用,如廣泛應用在計算機系統中的密碼加密,利用的就是不可逆加密算法。近年來,随着計算機系統性能的不斷提高,不可逆加密的應用領域正在逐漸增大。在計算機網絡中應用較多不可逆加密算法的有RSA公司發明的MD5算法和由美國國家标準局建議的不可逆加密标準SHS(Secure Hash Standard:安全雜亂資訊标準)等。 

DEA(Data Encryption Algorithm、DES)資料加密算法:是一種對稱加密算法,很可能是使用最廣泛的密鑰系統,特别是在保護金融資料的安全中,最初開發的DEA是嵌入硬體中的。通常,自動取款機(Automated Teller Machine,ATM)都使用DEA。它出自IBM的研究工作,IBM也曾對它擁有幾年的專利權,但是在1983年已到期後,處于公有範圍中,允許在特定條件下可以免除專利使用費而使用。1977年被美國政府正式采納。 

DES算法的安全性: 一.安全性比較高的一種算法,目前隻有一種方法可以破解該算法,那就是窮舉法. 二.采用64位密鑰技術,實際隻有56位有效,8位用來校驗的.譬如,有這樣的一台PC機器,它能每秒計算一百萬次,那麼256位空間它要窮舉的時間為2285年.是以這種算法還是比較安全的一種算法. 

TripleDES: 該算法被用來解決使用 DES 技術的 56 位時密鑰日益減弱的強度,其方法是:使用兩個獨立密鑰對明文運作 DES 算法三次,進而得到 112 位有效密鑰強度。TripleDES 有時稱為 DESede(表示加密、解密和加密這三個階段)。 

IDEA 國際資料加密算法:是旅居瑞士中國青年學者來學家和著名密碼專家J.Massey于1990年提出的。它在1990年正式公布并在以後得到增強。這種算法是在DES算法的基礎上發展出來的,類似于三重DES,和DES一樣IDEA也是屬于對稱密鑰算法。發展IDEA也是因為感到DES具有密鑰太短等缺點,已經過時。IDEA的密鑰為128位,這麼長的密鑰在今後若幹年内應該是安全的。 

RSA公鑰加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美國麻省理工學院)開發的。RSA取名來自開發他們三者的名字。RSA是目前最有影響力的公鑰加密算法,它能夠抵抗到目前為止已知的所有密碼攻擊,已被ISO推薦為公鑰資料加密标準。RSA算法基于一個十分簡單的數論事實:将兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,是以可以将乘積公開作為加密密鑰。 為提高保密強度,RSA密鑰至少為500位長,一般推薦使用1024位。這就使加密的計算量很大。為減少計算量,在傳送資訊時,常采用傳統加密方法與公開密鑰加密方法相結合的方式,即資訊采用改進的DES或IDEA對話密鑰加密,然後使用RSA密鑰加密對話密鑰和資訊摘要。對方收到資訊後,用不同的密鑰解密并可核對資訊摘要。RSA算法是第一個能同時用于加密和數字簽名的算法,也易于了解和操作。 

加密算法、DES、IDEA、RSA、DSA

RSA 加密算法的缺點: 1)産生密鑰很麻煩,受到素數産生技術的限制,因而難以做到一次一密。 2)安全性,RSA的安全性依賴于大數的因子分解,但并沒有從理論上證明破譯RSA的難度與大數分解難度等價,而且密碼學界多數人士傾向于因子分解不是NPC問題。 3)速度太慢,由于RSA 的分組長度太大,為保證安全性,n 至少也要 600 bitx以上,使運算代價很高,尤其是速度較慢,較對稱密碼算法慢幾個數量級;且随着大數分解技術的發展,這個長度還在增加,不利于資料格式的标準化。 

DSA(Digital Signature Algorithm):被美國國家标準局用來做DSS資料簽名标準(Digital Signature Standard)。DSA是基于整數有限域離散對數難題的,其安全性與RSA相比差不多。DSA的一個重要特點是兩個素數公開,這樣,當使用别人的p和q時,即使不知道私鑰,你也能确認它們是否是随機産生的,還是作了手腳。RSA算法卻做不到。DSA隻是一種算法,和RSA不同之處在于它不能用作加密和解密,也不能進行密鑰交換,隻用于簽名,它比RSA要快很多.

————————————————————————————————————————————————————————————

java實作

第1章基礎知識 

1.1. 單鑰密碼體制 

單鑰密碼體制是一種傳統的加密算法,是指資訊的發送方和接收方共同使用同一把密鑰進行加解密。 

通常,使用的加密算法比較簡便高效,密鑰簡短,加解密速度快,破譯極其困難。但是加密的安全性依靠密鑰保管的安全性,在公開的計算機網絡上安全地傳送和保管密鑰是一個嚴峻的問題,并且如果在多使用者的情況下密鑰的保管安全性也是一個問題。 

單鑰密碼體制的代表是美國的DES 

1.2. 消息摘要 

一個消息摘要就是一個資料塊的數字指紋。即對一個任意長度的一個資料塊進行計算,産生一個唯一指印(對于SHA1是産生一個20位元組的二進制數組)。 

消息摘要有兩個基本屬性: 

兩個不同的封包難以生成相同的摘要  

難以對指定的摘要生成一個封包,而由該封包反推算出該指定的摘要  

代表:美國國家标準技術研究所的SHA1和麻省理工學院Ronald Rivest提出的MD5 

1.3. Diffie-Hellman密鑰一緻協定 

密鑰一緻協定是由公開密鑰密碼體制的創始者Diffie和Hellman所提出的一種思想。 

先決條件,允許兩名使用者在公開媒體上交換資訊以生成"一緻"的,可以共享的密鑰 

代表:指數密鑰一緻協定(Exponential Key Agreement Protocol) 

1.4. 非對稱算法與公鑰體系 

1976年,Dittie和Hellman為解決密鑰管理問題,在他們的奠基性的工作"密碼學的新方向"一文中,提出一種密鑰交換協定,允許在不安全的媒體上通過通訊雙方交換資訊,安全地傳送秘密密鑰。在此新思想的基礎上,很快出現了非對稱密鑰密碼體制,即公鑰密碼體制。在公鑰體制中,加密密鑰不同于解密密鑰,加密密鑰公之于衆,誰都可以使用;解密密鑰隻有解密人自己知道。它們分别稱為公開密鑰(Public key)和秘密密鑰(Private key)。 

迄今為止的所有公鑰密碼體系中,RSA系統是最著名、最多使用的一種。RSA公開密鑰密碼系統是由R.Rivest、A.Shamir和L.Adleman俊教授于1977年提出的。RSA的取名就是來自于這三位發明者的姓的第一個字母 

1.5. 數字簽名 

所謂數字簽名就是資訊發送者用其私鑰對從所傳封包中提取出的特征資料(或稱數字指紋)進行RSA算法操作,以保證發信人無法抵賴曾發過該資訊(即不可抵賴性),同時也確定資訊封包在經簽名後末被篡改(即完整性)。當資訊接收者收到封包後,就可以用發送者的公鑰對數字簽名進行驗證。  

在數字簽名中有重要作用的數字指紋是通過一類特殊的散列函數(HASH函數)生成的,對這些HASH函數的特殊要求是: 

接受的輸入封包資料沒有長度限制;  

對任何輸入封包資料生成固定長度的摘要(數字指紋)輸出  

從封包能友善地算出摘要;  

難以對指定的摘要生成一個封包,而由該封包反推算出該指定的摘要;  

兩個不同的封包難以生成相同的摘要  

代表:DSA 

第2章在JAVA中的實作 

2.1. 相關 

Diffie-Hellman密鑰一緻協定和DES程式需要JCE工具庫的支援,可以到 http://java.sun.com/security/index.html 下載下傳JCE,并進行安裝。簡易安裝把 jce1.2.1\lib 下的所有内容複制到 %java_home%\lib\ext下,如果沒有ext目錄自行建立,再把jce1_2_1.jar和sunjce_provider.jar添加到CLASSPATH内,更詳細說明請看相應使用者手冊 

2.2. 消息摘要MD5和SHA的使用 

使用方法: 

首先用生成一個MessageDigest類,确定計算方法 

java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1"); 

添加要進行計算摘要的資訊 

alga.update(myinfo.getBytes()); 

計算出摘要 

byte[] digesta=alga.digest(); 

發送給其他人你的資訊和摘要 

其他人用相同的方法初始化,添加資訊,最後進行比較摘要是否相同 

algb.isEqual(digesta,algb.digest()) 

相關AIP 

java.security.MessageDigest 類 

static getInstance(String algorithm) 

傳回一個MessageDigest對象,它實作指定的算法 

參數:算法名,如 SHA-1 或MD5 

void update (byte input) 

void update (byte[] input) 

void update(byte[] input, int offset, int len) 

添加要進行計算摘要的資訊 

byte[] digest() 

完成計算,傳回計算得到的摘要(對于MD5是16位,SHA是20位) 

void reset() 

複位 

static boolean isEqual(byte[] digesta, byte[] digestb) 

比效兩個摘要是否相同 

代碼: 

import java.security.*; 

public class myDigest { 

  public static void main(String[] args)  { 

    myDigest my=new myDigest(); 

    my.testDigest(); 

  } 

  public void testDigest() 

  { 

   try { 

     String myinfo="我的測試資訊"; 

    //java.security.MessageDigest alg=java.security.MessageDigest.getInstance("MD5"); 

      java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1"); 

      alga.update(myinfo.getBytes()); 

      byte[] digesta=alga.digest(); 

      System.out.println("本資訊摘要是:"+byte2hex(digesta)); 

 //通過某中方式傳給其他人你的資訊(myinfo)和摘要(digesta) 對方可以判斷是否更改或傳輸正常 

      java.security.MessageDigest algb=java.security.MessageDigest.getInstance("SHA-1"); 

      algb.update(myinfo.getBytes()); 

      if (algb.isEqual(digesta,algb.digest())) { 

         System.out.println("資訊檢查正常"); 

       } 

       else 

        { 

          System.out.println("摘要不相同"); 

         } 

   } 

   catch (java.security.NoSuchAlgorithmException ex) { 

     System.out.println("非法摘要算法"); 

   } 

  } 

  public String byte2hex(byte[] b) //二行制轉字元串 

    { 

     String hs=""; 

     String stmp=""; 

     for (int n=0;n<b.length;n++) 

      { 

       stmp=(java.lang.Integer.toHexString(b[n] & 0XFF)); 

       if (stmp.length()==1) hs=hs+"0"+stmp; 

       else hs=hs+stmp; 

       if (n<b.length-1)  hs=hs+":"; 

      } 

     return hs.toUpperCase(); 

    } 

2.3. 數字簽名DSA 

對于一個使用者來講首先要生成他的密鑰對,并且分别儲存  

生成一個KeyPairGenerator執行個體 

   java.security.KeyPairGenerator  keygen=java.security.KeyPairGenerator.getInstance("DSA"); 

    如果設定随機産生器就用如相代碼初始化 

     SecureRandom secrand=new SecureRandom(); 

     secrand.setSeed("tttt".getBytes()); //初始化随機産生器 

     keygen.initialize(512,secrand);     //初始化密鑰生成器 

    否則 

     keygen.initialize(512); 

    生成密鑰公鑰pubkey和私鑰prikey 

      KeyPair keys=keygen.generateKeyPair(); //生成密鑰組 

      PublicKey pubkey=keys.getPublic(); 

      PrivateKey prikey=keys.getPrivate(); 

    分别儲存在myprikey.dat和mypubkey.dat中,以便下次不在生成 

    (生成密鑰對的時間比較長 

     java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat")); 

     out.writeObject(prikey); 

     out.close(); 

     out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat")); 

     out.writeObject(pubkey); 

     out.close(); 

用他私人密鑰(prikey)對他所确認的資訊(info)進行數字簽名産生一個簽名數組  

從檔案中讀入私人密鑰(prikey) 

   java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat")); 

    PrivateKey myprikey=(PrivateKey)in.readObject(); 

    in.close(); 

    初始一個Signature對象,并用私鑰對資訊簽名 

     java.security.Signature signet=java.security.Signature.getInstance("DSA"); 

     signet.initSign(myprikey); 

     signet.update(myinfo.getBytes()); 

     byte[] signed=signet.sign(); 

    把資訊和簽名儲存在一個檔案中(myinfo.dat) 

      java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat")); 

      out.writeObject(myinfo); 

      out.writeObject(signed); 

      out.close(); 

    把他的公鑰的資訊及簽名發給其它使用者 

其他使用者用他的公共密鑰(pubkey)和簽名(signed)和資訊(info)進行驗證是否由他簽名的資訊  

讀入公鑰 

java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat")); 

PublicKey pubkey=(PublicKey)in.readObject(); 

in.close(); 

讀入簽名和資訊 

in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat")); 

String info=(String)in.readObject(); 

byte[] signed=(byte[])in.readObject(); 

in.close(); 

初始一個Signature對象,并用公鑰和簽名進行驗證 

java.security.Signature signetcheck=java.security.Signature.getInstance("DSA"); 

signetcheck.initVerify(pubkey); 

signetcheck.update(info.getBytes()); 

if (signetcheck.verify(signed)) { System.out.println("簽名正常");} 

對于密鑰的儲存本文是用對象流的方式儲存和傳送的,也可可以用編碼的方式儲存.注意要 

import java.security.spec.* 

import java.security.* 

具休說明如下 

public key是用X.509編碼的,例碼如下:   byte[] bobEncodedPubKey=mypublic.getEncoded(); //生成編碼 

   //傳送二進制編碼 

   //以下代碼轉換編碼為相應key對象 

   X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey); 

   KeyFactory keyFactory = KeyFactory.getInstance("DSA"); 

   PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec); 

對于Private key是用PKCS#8編碼,例碼如下:  byte[] bPKCS=myprikey.getEncoded(); 

  //傳送二進制編碼 

  //以下代碼轉換編碼為相應key對象 

  PKCS8EncodedKeySpec priPKCS8=new PKCS8EncodedKeySpec(bPKCS); 

  KeyFactory keyf=KeyFactory.getInstance("DSA"); 

  PrivateKey otherprikey=keyf.generatePrivate(priPKCS8); 

常用API  

java.security.KeyPairGenerator 密鑰生成器類 

public static KeyPairGenerator getInstance(String algorithm) throws NoSuchAlgorithmException 

以指定的算法傳回一個KeyPairGenerator 對象 

參數: algorithm 算法名.如:"DSA","RSA" 

public void initialize(int keysize) 

以指定的長度初始化KeyPairGenerator對象,如果沒有初始化系統以1024長度預設設定 

參數:keysize 算法位長.其範圍必須在 512 到 1024 之間,且必須為 64 的倍數 

public void initialize(int keysize, SecureRandom random) 

以指定的長度初始化和随機發生器初始化KeyPairGenerator對象 

參數:keysize 算法位長.其範圍必須在 512 到 1024 之間,且必須為 64 的倍數 

random 一個随機位的來源(對于initialize(int keysize)使用了預設随機器 

public abstract KeyPair generateKeyPair() 

産生新密鑰對 

java.security.KeyPair 密鑰對類 

public PrivateKey getPrivate() 

傳回私鑰 

public PublicKey getPublic() 

傳回公鑰 

java.security.Signature 簽名類 

public static Signature getInstance(String algorithm) throws NoSuchAlgorithmException 

傳回一個指定算法的Signature對象 

參數 algorithm 如:"DSA" 

public final void initSign(PrivateKey privateKey) 

throws InvalidKeyException 

用指定的私鑰初始化 

參數:privateKey 所進行簽名時用的私鑰 

public final void update(byte data) 

throws SignatureException 

public final void update(byte[] data) 

throws SignatureException 

public final void update(byte[] data, int off, int len) 

throws SignatureException 

添加要簽名的資訊 

public final byte[] sign() 

throws SignatureException 

傳回簽名的數組,前提是initSign和update 

public final void initVerify(PublicKey publicKey) 

throws InvalidKeyException 

用指定的公鑰初始化 

參數:publicKey 驗證時用的公鑰 

public final boolean verify(byte[] signature) 

throws SignatureException 

驗證簽名是否有效,前提是已經initVerify初始化 

參數: signature 簽名數組 

 */ 

 import java.security.*; 

 import java.security.spec.*; 

public class testdsa { 

  public static void main(String[] args) throws java.security.NoSuchAlgorithmException,java.lang.Exception { 

        testdsa my=new testdsa(); 

        my.run(); 

  } 

  public void run() 

  { 

  //數字簽名生成密鑰 

  //第一步生成密鑰對,如果已經生成過,本過程就可以跳過,對使用者來講myprikey.dat要儲存在本地 

//而mypubkey.dat給釋出給其它使用者 

   if ((new java.io.File("myprikey.dat")).exists()==false) { 

       if (generatekey()==false) { 

           System.out.println("生成密鑰對敗"); 

           return; 

          }; 

        } 

//第二步,此使用者 

//從檔案中讀入私鑰,對一個字元串進行簽名後儲存在一個檔案(myinfo.dat)中 

//并且再把myinfo.dat發送出去 

//為了友善數字簽名也放進了myifno.dat檔案中,當然也可分别發送 

  try { 

  java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat")); 

  PrivateKey myprikey=(PrivateKey)in.readObject(); 

  in.close(); 

 // java.security.spec.X509EncodedKeySpec pubX509=new java.security.spec.X509EncodedKeySpec(bX509); 

 //java.security.spec.X509EncodedKeySpec pubkeyEncode=java.security.spec.X509EncodedKeySpec 

  String myinfo="這是我的資訊";    //要簽名的資訊 

  //用私鑰對資訊生成數字簽名 

  java.security.Signature signet=java.security.Signature.getInstance("DSA"); 

  signet.initSign(myprikey); 

  signet.update(myinfo.getBytes()); 

  byte[] signed=signet.sign();  //對資訊的數字簽名 

  System.out.println("signed(簽名内容)="+byte2hex(signed)); 

 //把資訊和數字簽名儲存在一個檔案中 

  java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat")); 

  out.writeObject(myinfo); 

  out.writeObject(signed); 

  out.close(); 

  System.out.println("簽名并生成檔案成功"); 

  } 

  catch (java.lang.Exception e) { 

    e.printStackTrace(); 

    System.out.println("簽名并生成檔案失敗"); 

  }; 

  //第三步 

  //其他人通過公共方式得到此戶的公鑰和檔案 

  //其他人用此戶的公鑰,對檔案進行檢查,如果成功說明是此使用者釋出的資訊. 

  // 

  try { 

   java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat")); 

   PublicKey pubkey=(PublicKey)in.readObject(); 

   in.close(); 

   System.out.println(pubkey.getFormat()); 

   in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat")); 

   String info=(String)in.readObject(); 

   byte[] signed=(byte[])in.readObject(); 

   in.close(); 

  java.security.Signature signetcheck=java.security.Signature.getInstance("DSA"); 

  signetcheck.initVerify(pubkey); 

  signetcheck.update(info.getBytes()); 

  if (signetcheck.verify(signed)) { 

  System.out.println("info="+info); 

   System.out.println("簽名正常"); 

  } 

  else  System.out.println("非簽名正常"); 

  } 

  catch (java.lang.Exception e) {e.printStackTrace();}; 

  } 

  //生成一對檔案myprikey.dat和mypubkey.dat---私鑰和公鑰, 

  //公鑰要使用者發送(檔案,網絡等方法)給其它使用者,私鑰儲存在本地 

  public boolean generatekey() 

  { 

    try { 

  java.security.KeyPairGenerator  keygen=java.security.KeyPairGenerator.getInstance("DSA"); 

 // SecureRandom secrand=new SecureRandom(); 

 // secrand.setSeed("tttt".getBytes()); //初始化随機産生器 

 // keygen.initialize(576,secrand);     //初始化密鑰生成器 

  keygen.initialize(512); 

  KeyPair keys=keygen.genKeyPair(); 

//  KeyPair keys=keygen.generateKeyPair(); //生成密鑰組 

  PublicKey pubkey=keys.getPublic(); 

  PrivateKey prikey=keys.getPrivate(); 

  java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat")); 

  out.writeObject(prikey); 

  out.close(); 

  System.out.println("寫入對象 prikeys ok"); 

  out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat")); 

   out.writeObject(pubkey); 

out.close(); 

   System.out.println("寫入對象 pubkeys ok"); 

   System.out.println("生成密鑰對成功"); 

   return true; 

  } 

  catch (java.lang.Exception e) { 

   e.printStackTrace(); 

   System.out.println("生成密鑰對失敗"); 

   return false; 

   }; 

  } 

  public String byte2hex(byte[] b) 

    { 

     String hs=""; 

     String stmp=""; 

     for (int n=0;n<b.length;n++) 

      { 

       stmp=(java.lang.Integer.toHexString(b[n] & 0XFF)); 

       if (stmp.length()==1) hs=hs+"0"+stmp; 

       else hs=hs+stmp; 

       if (n<b.length-1)  hs=hs+":"; 

      } 

     return hs.toUpperCase(); 

    } 

2.4. DESede/DES對稱算法 

首先生成密鑰,并儲存(這裡并沒的儲存的代碼,可參考DSA中的方法) 

KeyGenerator keygen = KeyGenerator.getInstance(Algorithm); 

SecretKey deskey = keygen.generateKey(); 

用密鑰加密明文(myinfo),生成密文(cipherByte) 

Cipher c1 = Cipher.getInstance(Algorithm); 

c1.init(Cipher.ENCRYPT_MODE,deskey); 

byte[] cipherByte=c1.doFinal(myinfo.getBytes()); 

傳送密文和密鑰,本文沒有相應代碼可參考DSA 

............. 

用密鑰解密密文 

c1 = Cipher.getInstance(Algorithm); 

c1.init(Cipher.DECRYPT_MODE,deskey); 

byte[] clearByte=c1.doFinal(cipherByte); 

相對來說對稱密鑰的使用是很簡單的,對于JCE來講支技DES,DESede,Blowfish三種加密術 

對于密鑰的儲存各傳送可使用對象流或者用二進制編碼,相關參考代碼如下 

   SecretKey deskey = keygen.generateKey(); 

   byte[] desEncode=deskey.getEncoded(); 

   javax.crypto.spec.SecretKeySpec destmp=new javax.crypto.spec.SecretKeySpec(desEncode,Algorithm); 

   SecretKey mydeskey=destmp; 

相關API 

KeyGenerator 在DSA中已經說明,在添加JCE後在instance進可以如下參數 

DES,DESede,Blowfish,HmacMD5,HmacSHA1 

javax.crypto.Cipher 加/解密器 

public static final Cipher getInstance(java.lang.String transformation) 

                                throws java.security.NoSuchAlgorithmException, 

                                       NoSuchPaddingException 

傳回一個指定方法的Cipher對象 

參數:transformation 方法名(可用 DES,DESede,Blowfish) 

public final void init(int opmode, java.security.Key key) 

throws java.security.InvalidKeyException 

用指定的密鑰和模式初始化Cipher對象 

參數:opmode 方式(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE) 

key 密鑰 

public final byte[] doFinal(byte[] input) 

                     throws java.lang.IllegalStateException, 

                            IllegalBlockSizeException, 

                            BadPaddingException 

對input内的串,進行編碼處理,傳回處理後二進制串,是傳回解密文還是加解文由init時的opmode決定 

注意:本方法的執行前如果有update,是對updat和本次input全部處理,否則是本inout的内容 

import java.security.*; 

import javax.crypto.*; 

public class testdes { 

public static void main(String[] args){ 

    testdes my=new testdes(); 

    my.run(); 

  } 

public  void run() { 

//添加新安全算法,如果用JCE就要把它添加進去 

 Security.addProvider(new com.sun.crypto.provider.SunJCE()); 

String Algorithm="DES"; //定義 加密算法,可用 DES,DESede,Blowfish 

String myinfo="要加密的資訊"; 

   try { 

   //生成密鑰 

   KeyGenerator keygen = KeyGenerator.getInstance(Algorithm); 

   SecretKey deskey = keygen.generateKey(); 

   //加密 

   System.out.println("加密前的二進串:"+byte2hex(myinfo.getBytes())); 

   System.out.println("加密前的資訊:"+myinfo); 

   Cipher c1 = Cipher.getInstance(Algorithm); 

   c1.init(Cipher.ENCRYPT_MODE,deskey); 

   byte[] cipherByte=c1.doFinal(myinfo.getBytes()); 

    System.out.println("加密後的二進串:"+byte2hex(cipherByte)); 

   //解密 

   c1 = Cipher.getInstance(Algorithm); 

   c1.init(Cipher.DECRYPT_MODE,deskey); 

   byte[] clearByte=c1.doFinal(cipherByte); 

   System.out.println("解密後的二進串:"+byte2hex(clearByte)); 

   System.out.println("解密後的資訊:"+(new String(clearByte))); 

  } 

   catch (java.security.NoSuchAlgorithmException e1) {e1.printStackTrace();} 

   catch (javax.crypto.NoSuchPaddingException e2) {e2.printStackTrace();} 

   catch (java.lang.Exception e3) {e3.printStackTrace();} 

  } 

 public String byte2hex(byte[] b) //二行制轉字元串 

    { 

     String hs=""; 

     String stmp=""; 

     for (int n=0;n<b.length;n++) 

      { 

       stmp=(java.lang.Integer.toHexString(b[n] & 0XFF)); 

       if (stmp.length()==1) hs=hs+"0"+stmp; 

       else hs=hs+stmp; 

       if (n<b.length-1)  hs=hs+":"; 

      } 

     return hs.toUpperCase(); 

    } 

2.5. Diffie-Hellman密鑰一緻協定 

公開密鑰密碼體制的創始者Diffie和Hellman所提出的 "指數密鑰一緻協定"(Exponential Key Agreement Protocol),該協定不要求

原文位址:http://www.zaoxue.com/article/tech-54324.htm