RSA签名与验签

简介: RSA签名与验签 RSA算法除了可以进行加解密以外,还可以用来签名与验签。RSA用来进行签名与验签时是使用私钥进行签名,公钥进行验签的。这点与加解密的时候刚好相反。加解密时使用公钥加密,私钥解密。

RSA签名与验签

RSA算法除了可以进行加解密以外,还可以用来签名与验签。RSA用来进行签名与验签时是使用私钥进行签名,公钥进行验签的。这点与加解密的时候刚好相反。加解密时使用公钥加密,私钥解密。签名和验签是通过Signature对象进行的。

签名

以下是一个使用Signature进行签名的示例。初始化Signature时指定将使用的签名算法是MD5withRSA,除了该算法外,Signature还支持很多其它的算法,如SHA256withRSA,更多的算法可以参考官方文档

	/**
	 * 测试签名
	 * @throws Exception
	 */
	@Test
	public void testSign() throws Exception {
		byte[] sign = this.sign("Hello World");
		String result = Base64.getEncoder().encodeToString(sign);
		System.out.println(result);
	}
	
	/**
	 * 私钥签名
	 * @param data
	 * @return
	 * @throws Exception
	 */
	private byte[] sign(String data) throws Exception {
		//读取储存的私钥字节数组
		byte[] privateKeyCode = Files.readAllBytes(Paths.get(PRIVATE_KEY_PATH));
		//包装私钥字节数组为一个KeySpec
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyCode);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
		//通过KeyFactory生成私钥
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		Signature signature = Signature.getInstance("MD5withRSA");//签名的算法
		//通过私钥初始化Signature,签名时用
		signature.initSign(privateKey);
		//指定需要进行签名的内容
		signature.update(data.getBytes());
		//签名
		byte[] result = signature.sign();
		return result;
	}

验签

以下是一个利用Signature进行验签的示例。验签时使用的是公钥。在初始化Signature时使用的是initVerify,而签名时使用的是initSign,这跟Cipher进行加解密有点类似。

	/**
	 * 测试公钥验签
	 * @throws Exception
	 */
	@Test
	public void testVerifySign() throws Exception {
		String data = "Hello World";
		byte[] sign = this.sign(data);
		Signature signature = Signature.getInstance("MD5withRSA");
		byte[] publicKeyCode = Files.readAllBytes(Paths.get(PUBLIC_KEY_PATH));
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyCode);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
		PublicKey publicKey = keyFactory.generatePublic(keySpec);
		//以验签的方式初始化Signature
		signature.initVerify(publicKey);
		//指定需要验证的签名
		signature.update(data.getBytes());
		//进行验签,返回验签结果
		boolean result = signature.verify(sign);
		Assert.assertTrue(result);
	}

完整代码 以下是上述示例的完整代码。

public class RSATest {

	private static final String ALGORITHM = "RSA";
	private static final String PRIVATE_KEY_PATH = "D:\\rsa_private.isa";
	private static final String PUBLIC_KEY_PATH = "D:\\rsa_public.isa";
	
	/**
	 * 测试签名
	 * @throws Exception
	 */
	@Test
	public void testSign() throws Exception {
		byte[] sign = this.sign("Hello World");
		String result = Base64.getEncoder().encodeToString(sign);
		System.out.println(result);
	}
	
	/**
	 * 私钥签名
	 * @param data
	 * @return
	 * @throws Exception
	 */
	private byte[] sign(String data) throws Exception {
		//读取储存的私钥字节数组
		byte[] privateKeyCode = Files.readAllBytes(Paths.get(PRIVATE_KEY_PATH));
		//包装私钥字节数组为一个KeySpec
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyCode);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
		//通过KeyFactory生成私钥
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		Signature signature = Signature.getInstance("MD5withRSA");//签名的算法
		//通过私钥初始化Signature,签名时用
		signature.initSign(privateKey);
		//指定需要进行签名的内容
		signature.update(data.getBytes());
		//签名
		byte[] result = signature.sign();
		return result;
	}
	
	/**
	 * 测试公钥验签
	 * @throws Exception
	 */
	@Test
	public void testVerifySign() throws Exception {
		String data = "Hello World";
		byte[] sign = this.sign(data);
		Signature signature = Signature.getInstance("MD5withRSA");
		byte[] publicKeyCode = Files.readAllBytes(Paths.get(PUBLIC_KEY_PATH));
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyCode);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
		PublicKey publicKey = keyFactory.generatePublic(keySpec);
		//以验签的方式初始化Signature
		signature.initVerify(publicKey);
		//指定需要验证的签名
		signature.update(data.getBytes());
		//进行验签,返回验签结果
		boolean result = signature.verify(sign);
		Assert.assertTrue(result);
	}
	
}

(注:本文由Elim写于2017年5月22日)

目录
相关文章
|
7月前
|
算法 安全 Java
Java 实现 RSA 非对称加密算法-加解密和签名验签
Java 实现 RSA 非对称加密算法-加解密和签名验签
295 0
|
Java Windows
签名验签工具
我们提供了一键生成RSA密钥工具。该工具也提供了签名及验签功能,可以演示针对支付宝开放平台接口的签名和验签流程。 WINDOWS版本下载地址:WINDOWS MAC OS版本下载地址:MAC_OSX 解压后,WINDOWS版本双击文件“RSA签名验签工具.bat”即可运行工具。
4356 0
|
7月前
|
存储 弹性计算 运维
生成签名私钥和证书
【4月更文挑战第29天】
52 1
由于没有公钥,无法验证下列签名: NO_PUBKEY 23E7166788B63E1E
由于没有公钥,无法验证下列签名: NO_PUBKEY 23E7166788B63E1E
221 0
|
Java 数据安全/隐私保护
java实现RSA加密、解密、签名
java实现RSA加密、解密、签名
1064 0
java实现RSA加密、解密、签名
|
存储 Web App开发 编解码
加解密,加签、验签也就这肥事
加解密,加签、验签也就这肥事
1661 0
加解密,加签、验签也就这肥事
|
算法 数据安全/隐私保护
RSA算法加密/解密和签名/验签工具类
RSA算法加密/解密和签名/验签工具类
|
XML 算法 安全
公钥 私钥 签名 验签 说的啥?
公钥 私钥 签名 验签 说的啥?
322 0
公钥 私钥 签名 验签 说的啥?
C++11 ECDSA-withSHA256验签
这里不做签名,只验签
278 0
|
C++
C++版本ECDSA-with-SHA256签名验证
由于项目需要验证签名,这里不做签名,只验签,所以直接上代码。
433 0