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

数字签名:带有密钥(公钥,私钥)的消息摘要算法   

私钥用于签名,公钥用于验证。


数字签名的作用:验证数据的完整性,认证数据来源,抗否认。

常用数字签名算法:RSA,DSA,ECDSA    

RSA:

RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。

算法分类信息:

算法 密钥长度 默认长度 签名长度 实现的方
MD2withRSA 512-65536
(64的整数倍)
1024 同密钥 JDK
MD5withRSA 同上 1024 同密钥 JDK
SHA1withRSA ... 1024 同密钥 JDK
SHA224withRSA ... 2048 同密钥 BC
SHA256withRSA ... 2048 同密钥 BC
SHA384withRSA ... 2048 同密钥 BC
SHA512withRSA ... 2048 同密钥 BC
RIPEMD128withRSA   2048 同密钥 BC
RIPEMD160withRSA 同上 2048 同密钥 BC

java实现:

/*
*Created on 2015年12月13日
*Copyright 2015 Yong Cai Limited crop. All Rights Reserved
*
*/

package org.cy.shuziqianming;

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 com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

public class RSA {
	private static String src = "rsa security";
	public static void main(String[] args) {
		jdkRSA();
	}
	
	public static void jdkRSA(){
		try {
			//1.初始化密钥
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
			keyPairGenerator.initialize(512);
			KeyPair keyPair = keyPairGenerator.generateKeyPair();
			RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
			RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
			
			//2.执行签名
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			java.security.Signature signature = java.security.Signature.getInstance("MD5withRSA");
			signature.initSign(privateKey);
			signature.update(src.getBytes());
			byte[] res = signature.sign();
			System.out.println("签名:"+HexBin.encode(res));
			
			//3.验证签名
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
			keyFactory.getInstance("RSA");
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			signature = Signature.getInstance("MD5withRSA");
			signature.initVerify(publicKey);
			signature.update(src.getBytes());
			boolean bool = signature.verify(res);
			System.out.println("验证:"+bool);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}


DSA:

DSA是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSfS(DigitalSignature Standard)。

DSA是基于整数有限域离散对数难题的,其安全性与RSA相比差不多。DSA的一个重要特点是两个素数公开,这样,当使用别人的p和q时,即使不知道私钥,你也能确认它们是否是随机产生的,还是作了手脚。RSA却做不到。

算法分类信息:

算法 密钥长度 默认长度 签名长度 实现的方
SHA1withDSA 512-65536
(64的整数倍)
1024 同密钥 JDK
SHA224withDSA 同上 1024 同密钥 BC
SHA256withDSA ... 1024 同密钥 BC
SHA384withDSA ... 1024 同密钥 BC
SHA512withDSA ... 1024 同密钥 BC

java实现:


/*
*Created on 2015年12月13日
*Copyright 2015 Yong Cai Limited crop. All Rights Reserved
*
*/

package org.cy.shuziqianming;

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.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

import sun.security.provider.DSAPrivateKey;
import sun.security.provider.DSAPublicKey;

public class DSA {
	private static String src = "dsa security";
	public static void main(String[] args) {
		jdkDSA();
	}
	
	public static void jdkDSA(){
		try {
			//1.初始化密钥 
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
			keyPairGenerator.initialize(512);
			KeyPair keyPair = keyPairGenerator.generateKeyPair();
			DSAPublicKey dsaPublicKey = (DSAPublicKey)keyPair.getPublic();
			DSAPrivateKey dsaPrivateKey = (DSAPrivateKey)keyPair.getPrivate();
			
			
			//2.执行签名
			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(src.getBytes());
			byte[] res = signature.sign();
			System.out.println("签名:"+HexBin.encode(res));
			
			//3.验证签名
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey.getEncoded());
			keyFactory = KeyFactory.getInstance("DSA");
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			signature = Signature.getInstance("SHA1withDSA");
			signature.initVerify(publicKey);
			signature.update(src.getBytes());
			boolean bool = signature.verify(res);
			System.out.println("验证:"+bool);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}


ECDSA:

ECDSA:椭圆曲线数字签名算法 

特点:速度快,强度高,签名短。

算法分类信息:

算法 密钥长度 默认长度 签名长度 实现的方
NONEwithECDSA 112-571 256 128 JDK/BC
RIPEMD160withECDSA 同上 256 160 BC
SHA1withECDSA ... 256 160 JDK/BC
SHA224withECDSA ... 256 224 BC
SHA256withECDSA ... 256 256 JDK/BC
SHA384withECDSA ... 256 384 JDK/BC
SHA512withECDSA ... 256 512 JDK/BC

java实现:

/*
*Created on 2015年12月13日
*Copyright 2015 Yong Cai Limited crop. All Rights Reserved
*
*/

package org.cy.shuziqianming;

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 com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

public class ECDSA {
	private static String src = "ecdsa security";
	public static void main(String[] args) {
		jdkECDSA();
	}
	
	public static void jdkECDSA(){
		try {
			//1.初始化密钥 
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
			keyPairGenerator.initialize(256);
			KeyPair keyPair = keyPairGenerator.generateKeyPair();
			ECPublicKey ecPublicKey = (ECPublicKey)keyPair.getPublic();
			ECPrivateKey ecPrivateKey = (ECPrivateKey)keyPair.getPrivate();
			
			
			//2.执行签名
			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(src.getBytes());
			byte[] res = signature.sign();
			System.out.println("签名:"+HexBin.encode(res));
			
			//3.验证签名
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(ecPublicKey.getEncoded());
			keyFactory = KeyFactory.getInstance("EC");
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			signature = Signature.getInstance("SHA1withECDSA");
			signature.initVerify(publicKey);
			signature.update(src.getBytes());
			boolean bool = signature.verify(res);
			System.out.println("验证:"+bool);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}




你可能感兴趣的:(Java)