欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数字签名介绍和java的实现

程序员文章站 2024-03-19 13:00:58
...

 

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

数字签名必须能保证以下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来实现这个数字签名就很容易了,通过java.security里面有RSADSA公开**算法的实现。

下面是部分代码

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

 

public static void generateKeypair() {
		KeyPairGenerator ******;
		FileOutputStream out = null;
		try {
			****** = KeyPairGenerator.getInstance("DSA");// 指定使用DSA算法
			******.initialize(1024, new SecureRandom());
			KeyPair pair = ******.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;
	}