JAVA RSA加密解决及数字签名实现代码

24 篇文章 0 订阅

1、代码

package com.zhaochao.utill;
import java.security.Key;
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 java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

public class RSACoder {
	public static final String KEY_ALGORITHM = "RSA";
	public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
	private static final String PUBLIC_KEY = "RSAPublicKey";
	private static final String PRIVATE_KEY = "RSAPrivateKey";

	public static String sign(byte[] data, String privateKey) throws Exception {
		// 解密由base64编码的私钥
		byte[] keyBytes = decryptBASE64(privateKey);
		// 构造PKCS8EncodedKeySpec对象
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		// KEY_ALGORITHM 指定的加密算法
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		// 取私钥匙对象
		PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
		// 用私钥对信息生成数字签名
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initSign(priKey);
		signature.update(data);
		return encryptBASE64(signature.sign());
	}

	public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
		// 解密由base64编码的公钥
		byte[] keyBytes = decryptBASE64(publicKey);
		// 构造X509EncodedKeySpec对象
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		// KEY_ALGORITHM 指定的加密算法
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		// 取公钥匙对象
		PublicKey pubKey = keyFactory.generatePublic(keySpec);
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initVerify(pubKey);
		signature.update(data);
		// 验证签名是否正常
		return signature.verify(decryptBASE64(sign));
	}

	public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
		// 对密钥解密
		byte[] keyBytes = decryptBASE64(key);
		// 取得私钥
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
		// 对数据解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		return cipher.doFinal(data);
	}

	public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
		// 对密钥解密
		byte[] keyBytes = decryptBASE64(key);
		// 取得公钥
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key publicKey = keyFactory.generatePublic(x509KeySpec);
		// 对数据解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, publicKey);
		return cipher.doFinal(data);
	}

	public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {
		// 对公钥解密
		byte[] keyBytes = decryptBASE64(key);
		// 取得公钥
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key publicKey = keyFactory.generatePublic(x509KeySpec);
		// 对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		return cipher.doFinal(data);
	}

	public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
		// 对密钥解密
		byte[] keyBytes = decryptBASE64(key);
		// 取得私钥
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
		// 对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
		return cipher.doFinal(data);
	}

	private static byte[] decryptBASE64(String key) throws Exception {
		// TODO Auto-generated method stub
		return Base64Utill.decodeBase64(key);
	}

	public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
		Key key = (Key) keyMap.get(PRIVATE_KEY);
		return encryptBASE64(key.getEncoded());
	}

	private static String encryptBASE64(byte[] encoded) throws Exception {
		// TODO Auto-generated method stub
		return Base64Utill.encodeBase64(encoded);
	}

	public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
		Key key = (Key) keyMap.get(PUBLIC_KEY);
		return encryptBASE64(key.getEncoded());
	}

	public static Map<String, Object> initKey() throws Exception {
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
		keyPairGen.initialize(1024);
		KeyPair keyPair = keyPairGen.generateKeyPair();
		// 公钥
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
		// 私钥
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
		Map<String, Object> keyMap = new HashMap<String, Object>(2);
		keyMap.put(PUBLIC_KEY, publicKey);
		keyMap.put(PRIVATE_KEY, privateKey);
		return keyMap;
	}

	public static void testEncode(String publicKey, String privateKey) throws Exception {
		System.err.println("公钥加密——私钥解密");
		String inputStr = "abc";
		byte[] data = inputStr.getBytes();
		byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey);
		byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData, privateKey);
		String outputStr = new String(decodedData);
		System.err.println("加密前: " + inputStr);
		System.err.println("加密后:" + new String(encodedData));
		System.err.println("解密后:" + outputStr);
		System.err.println(inputStr.equals(outputStr));


	}

	public static void testSign(String publicKey, String privateKey) throws Exception {
		System.err.println("私钥加密——公钥解密");
		String inputStr = "sign";
		byte[] data = inputStr.getBytes();
		byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);
		byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);
		String outputStr = new String(decodedData);
		System.err.println("加密前: " + inputStr + "==" + "解密后: " + outputStr);
		System.err.println(inputStr.equals(outputStr));
		System.err.println("私钥签名——公钥验证签名");
		// 产生签名
		String sign = RSACoder.sign(encodedData, privateKey);
		System.err.println("签名:" + sign);
		// 验证签名
		boolean status = RSACoder.verify(encodedData, publicKey, sign);
		System.err.println("状态:" + status);


	}

	public static void main(String[] rags) throws Exception {
		Map<String, Object> keyMap = RSACoder.initKey();
		String publicKey = RSACoder.getPublicKey(keyMap);
		String privateKey = RSACoder.getPrivateKey(keyMap);
		System.err.println("公钥: nr" + publicKey);
		System.err.println("私钥: nr" + privateKey);
		testEncode(publicKey, privateKey);
		testSign(publicKey, privateKey);

	}

}

2、BASE64加密文章

3、测试结果

公钥: nrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCcL1QiqQi6cR7FN61u8JxZrGuHUhQcCd5xinbLYRjLuriA1OY3SqnnUZAJQ7xQSIyPhufX7DjZTUqIux9RxSHsoOUPglxqLPudp4bXrVmICXiTeX7XlqlEJ3iBMIbWd9QXWfi9j6awX/8rBkssgnL7rVvYcJxqUN/6iMbRP6L0GQIDAQAB
私钥: nrMIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJwvVCKpCLpxHsU3rW7wnFmsa4dSFBwJ3nGKdsthGMu6uIDU5jdKqedRkAlDvFBIjI+G59fsONlNSoi7H1HFIeyg5Q+CXGos+52nhtetWYgJeJN5fteWqUQneIEwhtZ31BdZ+L2PprBf/ysGSyyCcvutW9hwnGpQ3/qIxtE/ovQZAgMBAAECgYBrMSRqYV7HLunyawMSF/sGpIpsJk387F0JygE8FljBQlZsvTF/kzPGubjEUwPEifZGb01haROfOCfGbb7SDRz5SvRK+O5+id7m9jxssqE0RaneWn+DPgaqiuVjHUFdYCYQpz9LrZvleennMZcT4v82jqrj7wS095e36L1uA7hrcQJBAMtwNVTt5VPNA8jV/VQQ7d9vTyHa2eBM5Ndz/tb+LCi7tEs/C/qiuPTnNaILS7J0O+3dCxBV2+JgelIjpesXTQ0CQQDEibB9xs8ntK1/zg0JkAx5VHsKrLHl3OyLiNT0AtMzJbNaIJMQh7bAiGxBt6X5Dahfn9gMWaJvipizl+PX9fg9AkEAhuEnSt7LTAtCNhbCdckfnSMUaRLLn237z2klje9I4dzJRZZQX+UhEaZ1pbEth+yOiz8hhbwXI/jpQKpH6B0zxQJBAMAxRX455GoXrXLFtModK5Wan5gYuP7nxAnPjS/xc0cZHwKLyETp8jTlM7gwNwYN7RFV5phtLwOUrS8y4YRW7KECQG/fO2HsWmZf/iF9sUa5lCeqt9KjHTQMmFC7j7ktaWuwXeqx27to/JfPe3kU0CWwWsKTrBYLYcY1ClM/za+yuuU=
公钥加密——私钥解密
加密前: abc
加密后:?"]Tރ���7��iJ����Cc�[ɠ�,��C�~EQ^w�\_B�S��M���r�S'ڲl7Z1��L��T�E��7�T�_�l%ѭ�L�|f��k��c�p,r��w�A
]�1U���Q|�
解密后:abc
true
私钥加密——公钥解密
加密前: sign==解密后: sign
true
私钥签名——公钥验证签名
签名:c4s5fSVDa6IrEIamAuJ5MxPADq7xsvJ5sVR3KguTLxWfsGZKTS4fCh01neiqZuRB/0e0d6n++cdDNwVwYrR6DQHINg2Uv3Y8mMzG0Sp/EnJAjqRmOP/b2kkIzAAS/UEuEdPLFSLex9cvVggdRK9V57XEeO0f7Qy7qaEcz+JmAZs=
状态:true


1、数字签名原理 用RSA算法做数字签名,总的来说,就是签名者用私钥参数d加密,也就是签名;验证者用签字者的公钥参数e解密来完成认证。 下面简要描述数字签名和认证的过程。 (1)、生成密钥 为用户随机生成一对密钥:公钥(e,n)和私钥(d,n). (2)、签名过程 a) 计算消息的散列值H(M). b) 用私钥(d,n)加密散列值:s=(H(M)) mod n,签名结果就是s. c) 发送消息和签名(M,s). (3)、认证过程 a) 取得发送方的公钥(e,n). b) 解密签名s:h=s mod n. c) 计算消息的散列值H(M). d) 比较,如果h=H(M),表示签名有效;否则,签名无效。 根据上面的过程,我们可以得到RSA数字签名的框图如图2-1: 图 2-1 RSA数字签名框图 2、 假设Alice想和Bob通信,以本地两个文件夹Alice和Bob模拟两个用户,实现消息M和签名的模拟分发 (1)、Alice通过RSA算法生成一对密钥:公钥(e,n)和私钥(d,n),将公私钥分别存入pubKey.txt和priKey.txt中。 pubKey.txt中公钥如下: priKey.txt中私钥如下: (2)、将Alice中的pubKey.txt拷到Bob中,模拟公玥的分发。 (3)、将Alice中的消息info.txt做散列,将散列后的值存入hashInfo.txt中。 (4)、将Alice中的消息hashInfo.txt和签名sign.txt拷到Bob中,实现M密文状态下的签名与模拟分发、消息传递。 (5)Bob取得公钥pubKey.txt,用公钥解密签名,计算消息的散列值H(M).比较,如果h=H(M),表示签名有效;否则,签名无效。 后台运行结果如下:
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵侠客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值