数字签名– RSA、DSA、ECDSA

原创 2016年08月30日 18:49:05

1、  什么是数字签名

数字签名,就是只有信息发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息发送者发送信息真实性的一个有效证明。

数字签名是带有密钥的消息摘要算法。数字签名实际上是一个工具,一次性生成秘钥后,将秘钥信息用于固定的交互中。

2、  数字签名的功能

保证信息传输的完整性、发送者的身份认证、防止交易中的抵赖发生。

首先由发送方构建密钥对,公布密钥对;发送方使用私钥根据摘要生成数字签名,将数字签名和数据报文一起发送给接收方;接收方使用公布的公钥对数字签名验证,验证通过则说明数据传输中没有被修改过,可正常接收,否则说明数据被修改过,可拒绝接收报文信息。

3、  数字签名测试代码

RSA、DSA、ECDSA 的代码编写近乎相同;全部粘贴出来,可以直接运行测试。

 1)RSA CODE

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Base64;

public class test {

	//摘要
	private static final String strMsg = "hold on";
	
	public static void main(String[] args) throws Exception {
		jdkRSA();
	}
	
	/**
	 * RSA 使用最为广泛的数字签名算法(MD、SHA两类)
	 * @throws Exception
	 */
	public static void jdkRSA() throws Exception{
		//1.初始化密钥
		KeyPair keyPair = initKey();
		
		//2.执行签名(用私钥签名)
		RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
		byte[] sign = privateKeySign(strMsg, rsaPrivateKey);
		String signStr = Base64.encodeBase64String(sign);  
		System.out.println("sign String :"+signStr);//数字签名格式转换,以便报文传输用
		
		RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
		String publicKeyStr =  Base64.encodeBase64String(rsaPublicKey.getEncoded());
		System.out.println("publicKeyStr String :"+publicKeyStr);//提供给对端,以便于对端使用公钥验证签名
		
		
		//3.验证签名(公钥验证签名)
		boolean result = publicKeyVerify(Base64.decodeBase64(signStr), Base64.decodeBase64(publicKeyStr));
		System.out.println("JDK RSA verify:"+result);
	}
	
	/**
	 * 1.初始化密钥,采用RSA
	 * @return
	 * @throws Exception 
	 */
	public static KeyPair initKey() throws Exception{
		KeyPairGenerator  keyPairGenerator = KeyPairGenerator.getInstance("RSA");
		keyPairGenerator.initialize(512); //key长度设置
		KeyPair keyPair = keyPairGenerator.generateKeyPair();
		
		return keyPair;
	}
	
	
	/**
	 * 2.执行签名(用私钥签名)
	 * @return
	 * @throws Exception 
	 */
	public static byte[] privateKeySign(String data,RSAPrivateKey rsaPrivateKey) throws Exception{
		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
		Signature signature = Signature.getInstance("MD5withRSA");
		signature.initSign(privateKey);
		signature.update(strMsg.getBytes());
		byte[] sign = signature.sign();
		
		return sign;
	}
	
	/**
	 * 3.公钥验证签名(摘要+签名串+公钥)
	 * @throws Exception 
	 */
	public static boolean publicKeyVerify(byte[] sign,byte[] rsaPublicKey) throws Exception{
		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
		Signature signature = Signature.getInstance("MD5withRSA");
		signature.initVerify(publicKey);
		signature.update(strMsg.getBytes());
		boolean result = signature.verify(sign);
		
		return result;
	}

}

 2)DSA CODE

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Base64;

public class test {

	//摘要
	private static final String strMsg = "hold on";
	
	public static void main(String[] args) throws Exception {
		jdkDSA();
	}
	
	/**
	 *  DSA code的编写与RSA近乎相同
	 * @throws Exception
	 */
	public static void jdkDSA() throws Exception{
		//1.初始化密钥
		KeyPair keyPair = initKey();
		
		//2.执行签名(用私钥签名)
		DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) keyPair.getPrivate();
		byte[] sign = privateKeySign(strMsg, dsaPrivateKey);
		String signStr = Base64.encodeBase64String(sign);  
		System.out.println("sign String :"+signStr);//数字签名格式转换,以便报文传输用
		
		DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic();
		String publicKeyStr =  Base64.encodeBase64String(dsaPublicKey.getEncoded());
		System.out.println("publicKeyStr String :"+publicKeyStr);//提供给对端,以便于对端使用公钥验证签名
		
		
		//3.验证签名(公钥验证签名)
		boolean result = publicKeyVerify(Base64.decodeBase64(signStr), Base64.decodeBase64(publicKeyStr));
		System.out.println("JDK DSA verify:"+result);
	}
	
	/**
	 * 1.初始化密钥,采用DSA
	 * @return
	 * @throws Exception 
	 */
	public static KeyPair initKey() throws Exception{
		KeyPairGenerator  keyPairGenerator = KeyPairGenerator.getInstance("DSA");
		keyPairGenerator.initialize(512); //key长度设置
		KeyPair keyPair = keyPairGenerator.generateKeyPair();
		
		return keyPair;
	}
	
	
	/**
	 * 2.执行签名(用私钥签名)
	 * @return
	 * @throws Exception 
	 */
	public static byte[] privateKeySign(String data,DSAPrivateKey dsaPrivateKey) throws Exception{
		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded());
		KeyFactory keyFactory = KeyFactory.getInstance("DSA");
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
		Signature signature = Signature.getInstance("SHA1withDSA");
		signature.initSign(privateKey);
		signature.update(strMsg.getBytes());
		byte[] sign = signature.sign();
		
		return sign;
	}
	
	/**
	 * 3.公钥验证签名(摘要+签名串+公钥)
	 * @throws Exception 
	 */
	public static boolean publicKeyVerify(byte[] sign,byte[] dsaPublicKey) throws Exception{
		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey);
		KeyFactory keyFactory = KeyFactory.getInstance("DSA");
		PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
		Signature signature = Signature.getInstance("SHA1withDSA");
		signature.initVerify(publicKey);
		signature.update(strMsg.getBytes());
		boolean result = signature.verify(sign);
		
		return result;
	}

}
 3)ECDSA  CODE

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Base64;

public class test {

	//摘要
	private static final String strMsg = "hold on";
	
	public static void main(String[] args) throws Exception {
		jdkECDSA();
	}
	
	/**
	 * ECDSA 微软的椭圆曲线算法 jdk1.7以后引入的算法
	 * @throws Exception
	 */
	public static void jdkECDSA() throws Exception{
		//1.初始化密钥
		KeyPair keyPair = initKey();
		
		//2.执行签名(用私钥签名)
		ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
		byte[] sign = privateKeySign(strMsg,ecPrivateKey);
		String signStr = Base64.encodeBase64String(sign);  
		System.out.println("sign String :"+signStr);//数字签名格式转换,以便报文传输用
		
		ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
		String publicKeyStr =  Base64.encodeBase64String(ecPublicKey.getEncoded());
		System.out.println("publicKeyStr String :"+publicKeyStr);//提供给对端,以便于对端使用公钥验证签名
		
		
		//3.验证签名(公钥验证签名)
		boolean result = publicKeyVerify(Base64.decodeBase64(signStr), Base64.decodeBase64(publicKeyStr));
		System.out.println("JDK DSA verify:"+result);
	}
	
	/**
	 * 1.初始化密钥,采用ECDSA
	 * @return
	 * @throws Exception 
	 */
	public static KeyPair initKey() throws Exception{
		KeyPairGenerator  keyPairGenerator = KeyPairGenerator.getInstance("EC");
		keyPairGenerator.initialize(256); //key长度设置
		KeyPair keyPair = keyPairGenerator.generateKeyPair();
		
		return keyPair;
	}
	
	
	/**
	 * 2.执行签名(用私钥签名)
	 * @return
	 * @throws Exception 
	 */
	public static byte[] privateKeySign(String data,ECPrivateKey ecPrivateKey) throws Exception{
		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded());
		KeyFactory keyFactory = KeyFactory.getInstance("EC");
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
		Signature signature = Signature.getInstance("SHA1withECDSA");
		signature.initSign(privateKey);
		signature.update(strMsg.getBytes());
		byte[] sign = signature.sign();
		
		return sign;
	}
	
	/**
	 * 3.公钥验证签名(摘要+签名串+公钥)
	 * @throws Exception 
	 */
	public static boolean publicKeyVerify(byte[] sign,byte[] dsaPublicKey) throws Exception{
		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey);
		KeyFactory keyFactory = KeyFactory.getInstance("EC");
		PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
		Signature signature = Signature.getInstance("SHA1withECDSA");
		signature.initVerify(publicKey);
		signature.update(strMsg.getBytes());
		boolean result = signature.verify(sign);
		
		return result;
	}

}



版权声明:

相关文章推荐

用Tomcat服务器配置https双向认证过程实战

HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入S...

keytool

使用Java自带的keytool命令,在命令行生成。  1、生成服务器端私钥kserver.keystore文件    keytool -genkey -alias serverk...

RSA、DSA和ECDSA三者的签名

数字签名就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。一般是非对称密钥加密技术与数字摘要技术的结合应用,目前主流的三种非对称算法...

RSA、DSA密钥对的生成

RSA、DSA密钥对的生成 4.3.5 RSA、DSA密钥对的生成 RSA、DSA密钥对的生成非常简单,只需一个命令即可完成。以下为密钥对的生成方法,具体步骤如下: 1. 生成RSA密钥对...

SSL--用Tomcat服务器配置https双向认证过程实战

转载自:http://blog.csdn.net/xxd851116/article/details/18701731 什么是https? 百度百科足够解释它:http://baike.ba...

RSA与ECC的选择

数字签名技术已经广泛使用于网络安全协议或分布式系统中,目前比较流行的数字签名算法有RSA和ECDSA。很多同学在产品设计中往往都难以区分RSA和ECDSA的优劣,所以笔者将基于自己的实践,来给出一些初...

数字签名加密算法(RSA、DSA、ECDSA)

RSA的例子:import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGe...
  • sx5273
  • sx5273
  • 2016-01-17 17:24
  • 1096

强制将 SSH 的host key type由 ECDSA替换为RSA

ssh -o HostKeyAlgorithms=ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ssh-rsa-cert-v00@...

java RSA/DSA/ECDSA实现数字签名

数字签名:带有密钥(公钥,私钥)的消息摘要算法    私钥用于签名,公钥用于验证。 数字签名的作用:验证数据的完整性,认证数据来源,抗否认。 常用数字签名算法:RSA,DSA,ECDSA   ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)