概念:
1.數字摘要:解決在安全的通信環境下,保證信息的唯一的一種方式。通常使用MD5/SHA-1等算法完成摘要。一般比如大家在網上下載軟件光盤時都會看到一個MD5值就是起到這個數字摘要的作用。在網絡的環境中發送者把消息和數字摘要一同發送給接收者,接收者使用發送者相同的算法對消息加密,看是否與發送者發送過來的數字摘要相同,如果相同就證明消息沒有給篡改過。下面是一個最為簡單的示例:
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(Digital Signature Algorithm (DSA)是Schnorr和ElGamal簽名算法的變種,被美國NIST作為DSS(DigitalSignature Standard))加密實現的。實現代碼如下:
*/ 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(); } } 把他的公鑰的信息及簽名發給其它用戶
4.PKI(公鑰基礎設施):