数字签名原理

数字签名是发送者通过摘要算法将正文生成摘要,并通过秘钥对摘要进行加密生成数字签名。接收方在接收到数字签名后通过秘钥对应的公钥进行解析出数字摘要,并对接收到的正文转换为数字摘要,并与解析出来的数字摘要进行对比,判断正文的完整性。其他人员无法冒充柱子签名。因为他们没有发送者的秘钥,并且内容不同生成的摘要也会不同,所以其他人员在篡改正文后,与数字签名无法形成对应,从而保证了数据的完整性。

数字签名的过程图如下:

数字签名校验如下图:

MD5withRSA

 MD5withRSA的算法实现

	//获取秘钥对
    public static KeyPair getKeyPair() throws Exception{ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(1024); return keyPairGenerator.generateKeyPair(); } //获取公钥 public static PublicKey getpublicKey() throws Exception{ Key key = getKeyPair().getPublic(); byte[] bytes = key.getEncoded(); byte[] bytesbase64 = Base64.encodeBase64(bytes); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(bytesbase64); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKeynew = keyFactory.generatePublic(x509KeySpec); return publicKeynew; }     //获取私钥 public static PrivateKey getprivateKey() throws Exception{ Key key = getKeyPair().getPublic(); byte[] bytes = key.getEncoded(); byte[] bytesbase64 = Base64.encodeBase64(bytes); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(bytesbase64); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); return privateKey; } //对正文进行数字签名 private static byte[] sign(byte[] content, PrivateKey privateKey) throws Exception{ MessageDigest md = MessageDigest.getInstance("MD5"); byte[] bytes = md.digest(content); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(bytes); }
    //对正文进行数字签名认证 private static boolean verify(byte[] content,PublicKey publicKey, byte[] sign) throws Exception{ MessageDigest md = MessageDigest.getInstance("MD5"); byte[] bytes = md.digest(content); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] signbyte = cipher.doFinal(bytes); byte[] base64 = Base64.encodeBase64(bytes); byte[] base64new = Base64.encodeBase64(bytes); if(base64.equals(base64new)){ return true; }else{ return false; } }

通过Signature API实现MD5withRSA算法

	private static byte[] signnew(byte[] content, PrivateKey privateKey) throws Exception{
		Signature signature = Signature.getInstance("MD5withRSA");
		signature.initSign(privateKey);
		signature.update(content);
		return signature.sign();
	}
	private static boolean verifynew(byte[] content, PublicKey publicKey, byte[] sign) throws Exception{
		Signature signature = Signature.getInstance("MD5withRSA");
		signature.initVerify(publicKey);
		signature.update(content);
		return signature.verify(sign);
	}

SHA1withRSA

 通过SHA1和RSA实现数字签名

	private static byte[] signsha(byte[] content,PrivateKey privateKey) throws Exception{
		MessageDigest md = MessageDigest.getInstance("SHA1");
		byte[] bytes = md.digest(content);
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
		return cipher.doFinal(bytes);
	}
	
	private static boolean verifysha(byte[] content,byte[] bytesha, PublicKey publicKey) throws Exception{
		MessageDigest md = MessageDigest.getInstance("SHA1");
		byte[] bytes = md.digest(content);
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, publicKey);
		byte[] byteshanew = cipher.doFinal(bytesha);
		byte[] bytebase64 = Base64.encodeBase64(bytes);
		byte[] bytebase64new = Base64.encodeBase64(byteshanew);
		if(bytebase64.equals(bytebase64new)){
			return true;
		}else {
			return false;
		}
	}

通过Signature API实现SHA1withRSA算法

	private static byte[] signShawithRSA(byte[] content,PrivateKey privateKey) throws Exception{
		Signature signature = Signature.getInstance("SHA1withRSA");
		signature.initSign(privateKey);
		signature.update(content);
		return signature.sign();
	}
	
	private static boolean verifyShawithRSA(byte[] content,byte[] bytersa,PublicKey publicKey) throws Exception{
		Signature signature = Signature.getInstance("SHA1withRSA");
		signature.initVerify(publicKey);
		signature.update(content);
		return signature.verify(bytersa);
	}