摘要:辦公自動化已滲透到企業管理中,與此同時,信息安全性也顯得尤為重要。由于計算機網絡的開放性的特點,公文流轉過程中的安全性、真實性和防抵賴性就顯得尤為重要了,在此研究領域中Java安全技術逐漸顯示出諸多的優勢,成為主流技術了。該課題針對公文流轉過程中存在的安全漏洞提出了基于Java安全技術下的數字簽名解決方案的框架,實踐證明該框架具有很高的可行性。
關鍵詞:公文流轉;Java;安全API;數字簽名
中圖分類號:TP309 文獻標識碼:A 文章編號:1009-3044(2008)35-2532-02
The Design and Implement of the Digital Ignature about Enterprises OA Document-trasferring
YAN Guang-ping
(Qilu Petrochemical Company,Zibo 255411,China)
Abstract: OA has entered into the common management of enterprises. at the same time, the importance of information security has been well known. Due to the opening characteristic of Internet, security, authenticity and prevent-deny have become more and more important. In this research field of security, The Java security technology has appeared more and more advantages and has become the mainstream. In this dissertation, the frame of resolving plans about digital signature based on Java security technology are pointed out, The plans can make up the leaks exist in the course of document-transferring in the office automation system. It proved by practice that the frame has high feasibility.
Key words: document transferring; Java; security API; digital signature
1 引言
目前,大多數企業在公文流轉子系統的文件收發管理中,收發文檔傳遞的是兩種形式的文本:公文正文(純文本)和附件(正規文檔),部門之間簡單的通知和消息以正文文本的形式傳遞,而正規的文檔則以附件的形式傳遞,由于涉及到企業的一些生產措施、內部政策文件甚至經濟效益等,其文件的保密性要求比較高,采用簡單的消息摘要不能滿足需求,必須對其進行數字簽名,保證信息的完整、不可抵賴以及安全性。為此,該文就辦公自動化公文流轉子系統的數字簽名的設計與實現進行探討。
2 數字簽名基本過程
一般來講,數字簽名過程如圖1所示,即首先計算被簽名文件的MD5碼或者SHA-1碼(java2程序缺省計算SHA-1碼),該碼經DSA私有密鑰和DSA加密算法加密后,形成數字簽名,然后附加到原文件中去,合并為可以向外發送的傳輸文件。收件人得到帶有數字簽名的傳輸文件后,要對數字簽名進行鑒別。首先,取出簽名者的公有密鑰,數字簽名經過公有密鑰和DSA解密算法解密后,恢復出原來的MD5碼,再與前者比較,如果相同,則文件屬實,否則文件或簽名被修改。
可以通過2種方案實現數字簽名:一是利用java自帶的相關工具實現;二是使用java.security API編寫類來實現。
以下,主要就用jdk1.2中的java.security.API構造類實現數字簽名進行分析。
3 用jdk1.2中的java.security.API構造類實現數字簽名
3.1 產生公鑰、私鑰對
得到密鑰產生器: KeyPairGenerator KeyGen= KeyPairGenerator. getInstance (“DSA”, ”SUN”);
初始化密鑰產生器:SecureRandom random= SecureRandom. getInstance (“MD5”,random);
產生公鑰和私鑰:KeyPair pair=KeyGen.generateKeyPair();
PrivateKey priv=pair.getPrivate();
PublicKey pub=pair.getPublic();
密鑰是由隨機數產生器產生的,在java中具體就是通過類KeyPairGenerator來生成的。生成一個“DSA”算法的密鑰對,長度為1024 bit,具體過程如下:
1) 創建密鑰對生成器首先生成一個KeyPairGenerator類的對象,成為密鑰對象:KeyPairGenerator KeyGen= KeyPairGenerator.getInstance(“DSA”);
2) 初始化密鑰對生成器KeyPairGenerator類中的initialize方法中的兩個參數:強度strength和隨機數源sourceofrandomness,將強度設置為1024,以生成1024位的密鑰對。將隨機數源設為內SecureRandom的一個實例,它將自動生成隨機數生成器運作說需要的一個seed值:
KeyGen.initialize(1024,new SecureRandom());
3) 生成密鑰對,將生成的密鑰對保存在KeyPair類的一個實例中:
KeyPair pair=KeyGen.GenerateKeyPair();
3.2 對數據簽名
得到一個簽名對象:
Signature dsa= Signature.getInstance(“SHA1withDSA”, ”SUN”);
初始化簽名對象:dsa.initSign(priv);
對數據簽名:das.update(buffer,0,len);
得到簽名的數據:byte[] realSig=dsa.sign()。
使用簽名類Signature來生成數字簽名。過程如下:
1) 得到一個簽名對象
使用DSA算法以及相應的SHA-1信息融合算法來得到一個生成和驗證簽名的簽名對象:Signature dsa= Signature.getInstance(“SHA/DSA”);
2) 初始化簽名對象,簽名對象用于簽名或驗證以前必須進行初始化,而這又需要用到前一步中生成的私有密鑰:
PrivateKey priv=pair.getPrivate();dsa.initSign(priv);
3) 為簽名對象提供需要簽名的數據,將指定文件(文件名由命令行中的第一個變量給出)的數據一次一個字節的讀出,并調用update方法把它提供給簽名對象。
FileInputStream data=new FileInputStream(args[0]);
Byte bTemp;
while(date.available()!=0)
{bTemp=(byte)data.read();
dsa.update(bTemp);
}
data.close();
4) 生成數字簽名,一旦把所有的數據提供給簽名對象,就可以對數據生成數字簽名。 byte[] realSig=dsa.sign();
5) 存儲簽名和公鑰
簽名結果直接按字節流存儲,公鑰通過pub.getEncoded();先轉換為字節流來處理。
6) 從文件中取得公鑰
先從文件中讀到字節流encKey中
構造一個密鑰說明類:
X509EncodedKeySpec pubKeySpec=new X509EncodedKeySpec(encKey);
構造一個密鑰管理器:
KeyFactory keyFactory= KeyFactory.getInstance(“DSA”,”SUN”);
取得公鑰:PublicKeypubKey=keyFactory.generatePublic(pubKeySpec);
3.3 驗證簽名
同生成簽名一樣先取得簽名對象,用公鑰初始化簽名對象:
Sig.initVerify(pubKey);
取得被簽名的數據:sig.update(buffer,0,len);
驗證:boolean verifies=sig.verify(sigToVerify)
對數字簽名進行驗證需要驗證一下3項內容:數據,數值簽名和密鑰中的私有密鑰,驗證過程如下所示:
1) 初始化簽名對象,初始化簽名對象時需要用到步驟1生成的密鑰對中的公有密鑰:PublicKey pub=pair.getPublic();
dsa.initVerify(pub);
2) 為簽名對象boolean result=dsa.verify(sig);
4 設計實現的應用程序
SignatureApp.java是本文生成和驗證數字簽名的應用程序。其主要程序段如下:
//generateKeyPair()方法
public Keypair generateKeyPair(){
try{KeyPairGenerate kg = KeyPairGenerateor.getInstance(“DSA”);
SecureRandom secrand = new SecureRandom();
kg.initialze(512,secrand);System.out.println(“Generating key pair…”);
keyPair keypair = kg.gentKeyPair();returm keyPair;
}catch(Exception e){ System.out.println(e);System.exit(0);}
return 1;}
//performFilesigning()方法給文件進行數字簽名,生成Singnature對象,然后將其通過initSign()方法初始化。
Public byte[] performFileSigning(byte[] s.KeyPair keypair){
try{ Signature sign = Signature.getInstance(“DSA”);
PublicKey publickey = keyPair,getPublic();
PrivateKey privatekey = keyPair/.getPrivate();sign.initSign(privatekey);
System.out.println(“Generating signature…”);sign.update(s);
byte[] b =sign.sign();SignatureBox,setText(“”);
SignatureBox.setText(“private key:\”) +conversion(privatekey.getEncode()));
SignatureBox.append(“\Signature:\”+conversion(b));
Return b; }catch(Exception e){
System.out.println(e);System.exit(0);}
return 1;}
//performTextVerification()方法驗證
public void performTextVerification(Strng s,byte[] signature,PublicKey publickey){
try{Signature sign = Signature.getInstance(“DAS”);
System.out.println(“\Verifying signature….”);Sign.initVerify(publickey);
sign..update(s.getBytes());if(sign.verify(signature))
signatureBox.appenf(“\Signature verified”);
else
SignatureBox.append(“\ Sinature NOT verified”);
}catch(Exception e){System.out.println(e);System.exit(0);}}
//performTextVerification()方法
public void performFileVerification(byte[] s,byte[] signature ,PublicKey publickey){try{Signature sign = Signature,getInstance(“DSA”);System.out.println(“\Verifying signature…”);sugn.initVerify(publickey);sign.update(s);if(sign,verfy(signature))
SignatureBox.append(“\Su\\ignature verified!”);
else
SignatureBox.append(“\Signature NOT verified!”);
}catch(Exception e){ System.out.println(e); System.exit(0);}}
參考文獻:
[1] RichHelton,JohennieHelton.java安全解決方案[M].袁泉,吳靜,等,譯.北京:清華大學出版社,2003.
[2] Garms,Jess.Somerfield,Daniel.java安全性指南[M].龐南,管和昌,等,譯.北京:電子工業出版社,2002.
[3] Mohan Atreya,等,著.數字簽名[M].賀軍,等,譯.北京:清華大學出版社,2003.
[4] 張先紅.數字簽名原理與技術[M].北京:機械工業出版社,2004.
[5] 裴繼奎,李大興.X.509中身份認證協議的安全性描述[J].計算機應用,2001(10):64-66.