package com.iuxi.security.algorithm; /** */ /** * 对文件进行DSA数字签名 * @author Iven * @DataTime 2006-12-12 0:58 * */ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import com.iuxi.security.util.Tool; public class DSAUtil ... { private PublicKey pubKey; private PrivateKey priKey; public String pubfile = ""; public String prifile = ""; public DSAUtil() ...{} public DSAUtil(String pubfile, String prifile) ...{ this.pubfile = pubfile; this.prifile = prifile; } /** *//** * 采用DSA算法生成非对称密钥对 * */ public void genKeys() ...{ try ...{ KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA"); SecureRandom secrand = new SecureRandom(); secrand.setSeed("random generator".getBytes()); keygen.initialize(512,secrand); //初始化密钥生成器 KeyPair keys = keygen.generateKeyPair();//生成密钥对 pubKey = keys.getPublic(); priKey = keys.getPrivate(); }catch(NoSuchAlgorithmException ex) ...{ ex.printStackTrace(); } } public String getPrifile() ...{ return prifile; } public void setPrifile(String prifile) ...{ this.prifile = prifile; } public String getPubfile() ...{ return pubfile; } public void setPubfile(String pubfile) ...{ this.pubfile = pubfile; } /** *//** * 保存密钥对信息到磁盘 * @param filepath1 公钥的存放路径 * @param filepath2 私钥的存放路径 */ public void saveKeys() ...{ if((!pubfile.equals(""))&&(!prifile.equals(""))) this.saveKeys(pubfile,prifile); else System.err.println("保存密钥出错,请先设置保存路径!"); } public void saveKeys(String filepath1, String filepath2) ...{ try ...{ FileOutputStream fos = new FileOutputStream(filepath1); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(pubKey); oos.close(); fos = new FileOutputStream(filepath2); oos = new ObjectOutputStream(fos); oos.writeObject(priKey); oos.close(); }catch(IOException ex) ...{ System.err.println("保存密钥对信息出错!"); ex.printStackTrace(); } } /** *//** * 从磁盘读取密钥信息 * @param filepath 密钥存放路径 * @return 返回密钥信息,为 Object 类,然后可根据具体的 PublicKey 或 PrivateKey 进行强制类型转换 */ private Object getKey(String filepath) ...{ Object obj = null; try ...{ FileInputStream fis = new FileInputStream(filepath); ObjectInputStream ois = new ObjectInputStream(fis); obj = ois.readObject(); ois.close(); }catch(IOException ex) ...{ System.err.println("读取密钥信息错误!"); }catch(ClassNotFoundException ex) ...{ ex.printStackTrace(); } return obj; } /** *//** * 获取公钥,如果当前公钥为空,则从磁盘文件读取,并将其设置为当前公钥,否则直接返回当前公钥 * @return 公钥 */ public PublicKey getPubKey() ...{ if(pubKey != null) return pubKey; if(!pubfile.equals("")) ...{ pubKey = (PublicKey)this.getKey(pubfile); return this.pubKey; } else ...{ System.err.println("读取公钥信息错误!"); return null; } } public PublicKey getPubKey(String filepath) ...{ pubKey = (PublicKey)this.getKey(filepath); return this.pubKey; } /** *//** * 获取私钥,如果当前私钥为空,则从磁盘文件读取,并将其设置为当前私钥,否则直接返回当前私钥 * @return 私钥 */ public PrivateKey getPriKey() ...{ if(priKey != null) return priKey; if(!prifile.equals("")) ...{ priKey = (PrivateKey)this.getKey(pubfile); return this.priKey; } else ...{ System.err.println("读取私钥信息错误!"); return null; } } public PrivateKey getPriKey(String filepath) ...{ priKey = (PrivateKey)this.getKey(filepath); return this.priKey; } /** *//** * 利用当前私钥对信息进行签名 * @return 签名信息(byte类型) */ public byte[] signBytes(byte[] info) ...{ byte[] signed = null; if(priKey == null) ...{ System.err.println("======== 提取密钥信息错误,无法完成签名 ========="); return null; } try ...{ Signature signet = Signature.getInstance("DSA"); signet.initSign(priKey); signet.update(info); signed = signet.sign(); }catch(NoSuchAlgorithmException ex) ...{ ex.printStackTrace(); }catch(InvalidKeyException ex) ...{ System.err.println("签名错误,无效的密钥"); ex.printStackTrace(); }catch(SignatureException ex) ...{ ex.printStackTrace(); } return signed; } /** *//** * 验证签名信息 * @param info 待验证的信息 * @param signed 该验证信息的签名 * @return 若验证正常,则返回 true , 否则返回 false */ public boolean checkSign(byte[] info, byte[] signed) ...{ if(pubKey == null) ...{ System.err.println("======== 提取密钥信息错误,无法完成签名 ========="); return false; } try ...{ Signature checkSignet = Signature.getInstance("DSA"); checkSignet.initVerify(pubKey); checkSignet.update(info); if(checkSignet.verify(signed)) ...{ System.out.println("======== 签名正常 ========="); return true; } else ...{ System.err.println("======== 签名信息异常 ========="); return false; } }catch(NoSuchAlgorithmException ex) ...{ ex.printStackTrace(); }catch(InvalidKeyException ex) ...{ System.err.println("验证签名错误,无效的密钥"); ex.printStackTrace(); }catch(SignatureException ex) ...{ ex.printStackTrace(); } return true; } public static void main(String[] args) ...{ DSAUtil dsa = new DSAUtil("pubKey.dat","priKey.dat"); dsa.genKeys(); dsa.saveKeys(); String test = "This is just a test!"; byte[] signedData = dsa.signBytes(test.getBytes()); System.out.println(Tool.byte2hex(signedData)); dsa.checkSign(test.getBytes(),signedData); }}