?
對稱解密的實現
對稱加密/解密算法在電子商務交易過程中存在幾個問題:
(1)?????? 要求提供一條安全的渠道使通訊雙方在首次通訊時協商一個共同的密鑰。直接的面對面協商可能是不現實而且難于實施的,所以雙方可能需要借助于郵件和電話等其它相對不夠安全的手段來進行協商;
(2)?????? 密鑰的數目難于管理。因為對于每一個合作者都需要使用不同的密鑰,很難適應開放社會中大量的信息交流;
(3)?????? 對稱加密算法一般不能提供信息完整性的鑒別。它無法驗證發送者和接受者的身份;
對稱密鑰的管理和分發工作是一件具有潛在危險的和煩瑣的過程。對稱加密是基于共同保守秘密來實現的,采用對稱加密技術的貿易雙方必須保證采用的是相同的密鑰,保證彼此密鑰的交換是安全可靠的,同時還要設定防止密鑰泄密和更改密鑰的程序。
對稱解密的代碼實現如下:
//從密鑰文件中讀密鑰
?? SecretKey key=null;
?? try
?? {ObjectInputStream keyFile=new ObjectInputStream(
???? new FileInputStream("c:\\安全文件\\"+misClass.username+"\\對稱\\對稱密鑰\\yhb.des"));
??? key=(SecretKey)keyFile.readObject();
??? keyFile.close();
??? }
??? catch(FileNotFoundException ey1)
??? {
??? System.out.println("Error when read keyFile");
??? System.exit(0);
??? }
??? catch(Exception ey2)
??? {
??? System.out.println("error when read the keyFile");
??? System.exit(0);
??? }
?? //用key產生Cipher
??? Cipher cipher=null;
??? try
{
//設置算法,應該與加密時的設置一樣
cipher=Cipher.getInstance("DES");
//設置解密模式
???? cipher.init(Cipher.DECRYPT_MODE,key);
???? }catch(Exception ey3)
???? {
???? System.out.println("Error when create the cipher");
???? System.exit(0);
???? }
???? //從對話框中取得要解密的文件并解密
???? File file=new File(dirstring,string1);
???? String filename=file.getName();
??? try
{
//輸出流,請注意文件名稱的獲取
BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(
????????? "c:\\安全文件\\文件\\"+filename.substring(0,filename.length()-4)));
???? //輸入流
????? CipherInputStream in=new CipherInputStream(new BufferedInputStream(
??????????? new FileInputStream(file)),cipher);
??? int thebyte=0;
??? while((thebyte=in.read())!=-1)
??? {
??? out.write(thebyte);
??? }
????? in.close();
????? out.close();
????? }
????? catch(Exception ey5)
????? {
????? System.out.println("Error when encrypt the file");
????? System.exit(0);
????? }
簽名的實現過程
1)讀取自己的私鑰
??? 對于自己的私鑰文件,要用File類來聲明。讀取時,將用FileInputStream格式來作為輸入流。而讀出的密鑰是字節數組,所以應該將讀出的密鑰用ByteArrayOutStream來保存,再用toByteArray格式來將它轉化為字節數組。
生成簽名要使用自己的私鑰,而私鑰使用PKCS8#編碼。所以我們還要將字節數組轉化為PKCS8#編碼形式。實現方法如下:
PKCS8EncodedKeySpec keyspec=new PKCS8EncodedKeySpec(keybytes);
KeyFactory keyfactory=KeyFactory.getInstance("RSA");
syprivatekey=keyfactory.generatePrivate(keyspec);
其中keybytes是從原文中讀出的字節數組形式的密鑰。用KeyFactory對象的實例化方法來指定算法,并用generatePrivate方法產生PKCS8#編碼的私鑰。
2)從對話框中取得要簽名的文件
該步驟的實現比較簡單,不做過多說明。
3)將文件內容讀取為字節數組格式
因為簽名時Signature類的Update()方法的參數是字節數組形式,所以要求
先將原文讀為字節數組。并且,在此處可以獲得原文的內容長度。
4)生成簽名
按照前面的描述,先用Signature類的getInstance()方法指定MD5WithRSA
算法,然后用前面得到的私鑰作為參數調用initSign()方法來初始化,最后用原文作為參數調用update()方法來傳送數據,用字節數組形式的私鑰作為參數調用Sign()方法來產生簽名。
將生成的簽名按照前面設計的文件格式寫入文件流中,就完成了簽名的全部工作。簽名的實現過程可用下面的圖來表示:

?????圖 數字簽名過程
代碼實現如下:
//讀取私鑰
???? PrivateKey syprivatekey=null;
????? File syfile=new File("c:\\安全文件\\"+misClass.username+"\\非對稱\\本人公私鑰\\yhb.private");
????? try
???? {
???? FileInputStream fis=new FileInputStream(syfile);
???? ByteArrayOutputStream baos=new ByteArrayOutputStream();
?
???? int thebyte=0;
????? while((thebyte=fis.read())!=-1)
????? {baos.write(thebyte);
????? }
????? fis.close();
????? byte[] keybytes=baos.toByteArray();
????? baos.close();
?
????? PKCS8EncodedKeySpec keyspec=new PKCS8EncodedKeySpec(keybytes);
????? KeyFactory keyfactory=KeyFactory.getInstance("RSA");
????? syprivatekey=keyfactory.generatePrivate(keyspec);
??? }
??? catch(Exception e9)
???? {
???? System.out.print("error when read the rsa private key");
???? System.exit(0);
???? }
???? //從對話框中取得要簽名的文件
???? File file=new File(dirstring1,string1);
???? String filename=file.getName();
???? //首先將文件讀為byte[]對象
??? int len=(int)file.length();
??? if(len>100000000)
??? {System.out.println("the file length is too long!");
??? System.exit(0);
??? }
??? byte[] inbuf=new byte[len];
??? try{
??? FileInputStream instream=new FileInputStream(file);
??? int inbytes=instream.available();
??? //inbuf[]=new byte[inbytes];
??? int bytesread=instream.read(inbuf,0,inbytes);
??? instream.close();
??? //System.out.println(inbuf);
??? }
??? catch(Exception eq2)
??? {
??? System.out.println("error when change the file to byte[]");
??? System.exit(0);
??? }
??? //簽名的具體過程
??? try{
??? //byte[] signaturebytes=new byte[150];
??? Signature sig=Signature.getInstance("MD5WithRSA");
??? sig.initSign(syprivatekey);
??? sig.update(inbuf);
??? byte[] signaturebytes=sig.sign();
?????????? //寫入對象流中
?? DataOutputStream outfile=new DataOutputStream(new FileOutputStream(
????????????????? "c:\\安全文件\\文件\\"+filename+".yhb3"));
??? outfile.writeInt(signaturebytes.length);
??? outfile.write(signaturebytes);
??? outfile.writeInt(len);
??? outfile.write(inbuf);
??? outfile.close();
??? }
??? catch(Exception eh3)
??? {
??? System.out.println("error when generate the outfile");
??? System.exit(0);
??? }
?
?