`
ttkktt
  • 浏览: 27315 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

数字签名介绍和java的实现

阅读更多

 

现实中的文件和书信我们可以通过印章来确定它的有效和可信性,那么在计算机网络中传送的报文如何保证呢?这就是数字签名要解决的问题。

数字签名必须能保证以下3点

1.接收者能够核实发送者对报文的签名。

2.发送者事后不能抵赖对报文的签名。

3.接收者不能伪造对报文的签名。

 

目前已经存在着各种各样数字签名方法。今天为大家介绍一种java中比较容易实现的公开密钥算法来做数字签名。首先介绍一下公开密钥算法实现数字签名的原理:

 

公开密钥算法有以下特点:

1.加密密钥PK对明文X加密后,用解密密钥SK解密即可恢复出原明文。另外加密和解密运算可以互换。

       公式为:Dsk(Epk(X))=X Epk(Dsk(X))=X

2.加密密钥PK是公开的,但通过PK无法推导出SK

 

2个特点正好满足了数字签名的3点要求。下图是用公开密钥算法实现数字签名的原理图

 


有了以上的知识用java来实现这个数字签名就很容易了,通过java.security里面有RSADSA公开密钥算法的实现。

下面是部分代码

generateKeypair方法生成PKSK,你只需要把SK保存下来用

 

public static void generateKeypair() {
		KeyPairGenerator keyGen;
		FileOutputStream out = null;
		try {
			keyGen = KeyPairGenerator.getInstance("DSA");// 指定使用DSA算法
			keyGen.initialize(1024, new SecureRandom());
			KeyPair pair = keyGen.generateKeyPair();
			pk = pair.getPublic();
			sk = pair.getPrivate();

			out = new FileOutputStream(System.getProperty("user.dir")
					+ "\\sk.dat");
			String tmpsk = StringUtil.encodeHex(sk.getEncoded());
			out.write(tmpsk.getBytes());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

 generateSignature方法通过sk对明文进行签名,返回值是对明文的签名

public String generateSignature(File inFile, PrivateKey privKey) {
		Signature dsa;
		FileInputStream fis = null;
		try {
			dsa = Signature.getInstance("DSA");
			dsa.initSign(privKey);
			fis = new FileInputStream(inFile);

			SAXReader reader = new SAXReader();
			Document doc = reader.read(fis);
			dsa.update(doc.asXML().getBytes());

			byte[] signature = dsa.sign();
			return StringUtil.encodeHex(signature);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (SignatureException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		} finally {
			try {
				if (fis != null)
					fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

 validData方法对收到的数据进行签名验证

public boolean validData (byte[] data,String publicKey,String signature) {

		try { // valid the file with public key and signature
			byte[] encodedpubKey = StringUtil.decodeHex(publicKey);

			X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(
					encodedpubKey);
			KeyFactory keyFactory;
			keyFactory = KeyFactory.getInstance("DSA");
			PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
			byte[] sign = StringUtil.decodeHex(signature);

			Signature s = Signature.getInstance("DSA");
			s.initVerify(pubKey);
			s.update(data);
			boolean flag = s.verify(sign);
			return flag;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (SignatureException e) {
			e.printStackTrace();
		}
		return false;
	}

 

 

 

  • 大小: 15.5 KB
3
1
分享到:
评论
2 楼 ttkktt 2009-06-04  
StringUtil.decodeHex和encodeHex方法是自己写的对签名转换成Hex码的方法。
1 楼 ivyloo 2009-06-03  
有帮助,谢谢!
另外请问,StringUtil.encodeHex(signature);   在什么包中可取得该方法?

相关推荐

Global site tag (gtag.js) - Google Analytics