RSA 密钥对生成、数据的加密解密以及验签

1.两种方式的数据加密
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import com.java.web.test.RasKeyPairGenerator;

public class RsaEncryptionAndDecryption {

	/***
	 * RSA 加解密
	 * 
	 * @param agrs
	 */
	public static void main(String agrs[]) throws Exception {
		String data = "qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm";
		/***
		 * 如果未生成公钥和私钥文件执行 RasKeyPairGenerator.writeKey();
		 */
		// RasKeyPairGenerator.writeKey();//生成公钥私钥并写入文件
		/***
		 * 方式一:读取公钥私钥文件并验证数据的加解密
		 */
		// encryptionAndDecryption(data);
		/***
		 * 方式二:读取公钥私钥文件并验证数据的加解密(n,e,d)
		 */
		encryptionAndDecryptionByNED(data);
		String publicKeyPath = "d:\\PublicKey.xml";
		String privateKeyPath = "d:\\PrivateKey.xml";
		String publicKey = RasKeyPairGenerator.readKey(publicKeyPath);
		String privateKey = RasKeyPairGenerator.readKey(privateKeyPath);
		String encode = "UTF8";
		String signStr = new String(RSASignature.sign(data, privateKey, encode));
		System.out.println("签名 data:"+ signStr);
		boolean check = RSASignature.doCheck(data, signStr, publicKey, encode);
		if (!true) {
			System.out.println("验签失败");
		} else {
			System.out.println("验签成功");
		}
	}

	/***
	 * 读取公钥和私钥,进行数据加解密
	 * 
	 * @param data
	 */
	public static void encryptionAndDecryption(String data) {

		try {
			// 获取公钥
			String publicKeyPath = "d:\\PublicKey.xml";
			PublicKey publicKey = RasKeyPairGenerator.getPublicKey(RasKeyPairGenerator.readKey(publicKeyPath));
			// 获取私钥
			String privateKeyPath = "d:\\PrivateKey.xml";
			PrivateKey privateKey = RasKeyPairGenerator.getPrivateKey(RasKeyPairGenerator.readKey(privateKeyPath));
			MD5 md5 = new MD5();
			// MD5是防止加密数据的长度过长而引起异常 javax.crypto.IllegalBlockSizeException:Data must not be longer than 117 bytes
			data = md5.digest(data, "MD5");
			System.out.println("MD5 data:" + data);
			// 公钥加密
			byte[] encryptedBytes = RasKeyPairGenerator.encrypt(data.getBytes(), publicKey);
			System.out.println("公钥加密:" + new String(encryptedBytes));
			// 私钥解密
			byte[] decryptedBytes = RasKeyPairGenerator.decrypt(encryptedBytes, privateKey);
			System.out.println("私钥解密:" + new String(decryptedBytes));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("加解密异常:" + e);
		}
	}

	/***
	 * 由n和e获取公钥,由n和d获取私钥,进行数据加解密
	 * 
	 * @param data
	 */
	public static void encryptionAndDecryptionByNED(String data) {

		try {
			// 获取公钥
			String publicKeyPath = "d:\\PublicKey.xml";
			RSAPublicKey rsaPublicKey = (RSAPublicKey) RasKeyPairGenerator
					.getPublicKey(RasKeyPairGenerator.readKey(publicKeyPath));
			String modulus1 = rsaPublicKey.getModulus().toString();
			String exponent1 = rsaPublicKey.getPublicExponent().toString();
			// 获取私钥
			String privateKeyPath = "d:\\PrivateKey.xml";
			RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) RasKeyPairGenerator
					.getPrivateKey(RasKeyPairGenerator.readKey(privateKeyPath));
			String modulus2 = rsaPrivateKey.getModulus().toString();
			String exponent2 = rsaPrivateKey.getPrivateExponent().toString();
			MD5 md5 = new MD5();
			// MD5是防止加密数据的长度过长而引起异常
			data = md5.digest(data, "MD5");
			// 由n和e获取公钥
			PublicKey publicKey = RasKeyPairGenerator.getPublicKey(modulus1, exponent1);
			// 由n和d获取私钥
			PrivateKey privateKey = RasKeyPairGenerator.getPrivateKey(modulus2, exponent2);
			System.out.println("MD5 data:" + data);
			// 公钥加密
			byte[] encryptedBytes = RasKeyPairGenerator.encrypt(data.getBytes(), publicKey);
			String jia = RasKeyPairGenerator.encryptBASE64(encryptedBytes);
			System.out.println("公钥加密:" + new String(encryptedBytes));
			System.out.println("公钥加密: base64编码:" + jia);
			// 私钥解密
			String jie = new String(RasKeyPairGenerator.decrypt(RasKeyPairGenerator.decryptBASE64(jia), privateKey));
			byte[] decryptedBytes = RasKeyPairGenerator.decrypt(encryptedBytes, privateKey);
			
			System.out.println("私钥解密:" + new String(decryptedBytes));
			System.out.println("私钥解密: base64解码:" + jie);
		} catch (Exception e) {
			System.out.println("加解密异常:" + e);
		}
	}
}
2.RSA工具类
import java.io.File;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
import com.java.web.util.FileUtil;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class RasKeyPairGenerator {
	/***
	 * 生成密钥对并写入文件
	 * 
	 * @throws Exception
	 */
	public static void writeKey() throws Exception {
		KeyPair keyPair = genKeyPair(1024);
		// 公钥
		PublicKey publicKey = keyPair.getPublic();
		String publicKeyName = "d:\\PublicKey.xml";
		String publicKeyContent = new String(Base64.getEncoder().encode(publicKey.getEncoded()));
		// 私钥
		PrivateKey privateKey = keyPair.getPrivate();
		String privateKeyContent = new String(Base64.getEncoder().encode(privateKey.getEncoded()));
		String privateKeyName = "d:\\PrivateKey.xml";
		FileUtil.makeNewFile(publicKeyName, publicKeyContent);
		FileUtil.makeNewFile(privateKeyName, privateKeyContent);
	}

	/***
	 * 生成密钥对
	 * 
	 * @param keyLength
	 * @return
	 * @throws Exception
	 */
	public static KeyPair genKeyPair(int keyLength) throws Exception {
		KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
		keyPairGenerator.initialize(keyLength);
		return keyPairGenerator.generateKeyPair();
	}

	/***
	 * 公钥加密
	 * 
	 * @param content
	 * @param publicKey
	 * @return
	 * @throws Exception
	 */
	public static byte[] encrypt(byte[] content, PublicKey publicKey) throws Exception {
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		return cipher.doFinal(content);
	}

	/***
	 * 私钥解密
	 * 
	 * @param content
	 * @param privateKey
	 * @return
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] content, PrivateKey privateKey) throws Exception {
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		return cipher.doFinal(content);
	}

	/***
	 * 将base64编码后的公钥字符串转成PublicKey实例
	 * 
	 * @param publicKey
	 * @return
	 * @throws Exception
	 */
	public static PublicKey getPublicKey(String publicKey) throws Exception {
		byte[] keyBytes = Base64.getDecoder().decode(publicKey.getBytes());
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return keyFactory.generatePublic(keySpec);
	}

	/***
	 * 将base64编码后的私钥字符串转成PrivateKey实例
	 * 
	 * @param privateKey
	 * @return
	 * @throws Exception
	 */
	public static PrivateKey getPrivateKey(String privateKey) throws Exception {
		byte[] keyBytes = Base64.getDecoder().decode(privateKey.getBytes());
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return keyFactory.generatePrivate(keySpec);
	}

	/***
	 * 将base64编码后的公钥字符串转成PublicKey实例 由n和e获取公钥
	 * 
	 * @param modulusStr
	 * @param exponentStr
	 * @return
	 * @throws Exception
	 */
	public static PublicKey getPublicKey(String modulusStr, String exponentStr) throws Exception {
		BigInteger modulus = new BigInteger(modulusStr);
		BigInteger exponent = new BigInteger(exponentStr);
		RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(modulus, exponent);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return keyFactory.generatePublic(publicKeySpec);
	}

	/***
	 * 将base64编码后的私钥字符串转成PrivateKey实例 由n和d获取私钥
	 * 
	 * @param modulusStr
	 * @param exponentStr
	 * @return
	 * @throws Exception
	 */
	public static PrivateKey getPrivateKey(String modulusStr, String exponentStr) throws Exception {
		BigInteger modulus = new BigInteger(modulusStr);
		BigInteger exponent = new BigInteger(exponentStr);
		RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(modulus, exponent);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return keyFactory.generatePrivate(privateKeySpec);
	}

	/***
	 * 从文件中读取公钥私钥
	 * 
	 * @param filePath
	 * @return
	 */
	public static String readKey(String filePath) {
		File file = FileUtil.getFile(filePath);
		return FileUtil.getFileContent(file);
	}

	/***
	 * encode:编码
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encryptBASE64(byte[] key) throws Exception {
		return (new BASE64Encoder()).encodeBuffer(key);
	}

	/***
	 * decode:解码
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptBASE64(String key) throws Exception {
		return (new BASE64Decoder()).decodeBuffer(key);
	}
}
3.MD5
    public String digest(byte[] src, String name) throws Exception {
        if (name.equals("MD5")) {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(src);
            byte[] encodeBase64 = Base64.encodeBase64(digest);
            String newPasswd = new String(encodeBase64, "UTF-8");
            return newPasswd;
        } else {
            return StringUtils.EMPTY;
        }
    }
4.签名工具类
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import com.java.web.test.RasKeyPairGenerator;

/**
 * RSA签名验签类
 */
public class RSASignature {

	/**
	 * 签名算法
	 */
	public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

	/**
	 * RSA签名
	 * 
	 * @param content
	 *            待签名数据
	 * @param privateKey
	 *            商户私钥
	 * @param encode
	 *            字符集编码
	 * @return 签名值
	 */
	public static String sign(String content, String privateKey, String encode) {
		try {
			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(RasKeyPairGenerator.decryptBASE64(privateKey));

			KeyFactory keyf = KeyFactory.getInstance("RSA");
			PrivateKey priKey = keyf.generatePrivate(priPKCS8);

			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

			signature.initSign(priKey);
			signature.update(content.getBytes(encode));

			byte[] signed = signature.sign();

			return new String(RasKeyPairGenerator.encryptBASE64(signed));
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public static byte[] sign(String content, String privateKey) {
		try {
			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(RasKeyPairGenerator.decryptBASE64(privateKey));
			KeyFactory keyf = KeyFactory.getInstance("RSA");
			PrivateKey priKey = keyf.generatePrivate(priPKCS8);
			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
			signature.initSign(priKey);
			signature.update(content.getBytes());
			byte[] signed = signature.sign();
			return signed;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * RSA验签名检查
	 * 
	 * @param content
	 *            待签名数据
	 * @param sign
	 *            签名值
	 * @param publicKey
	 *            分配给开发商公钥
	 * @param encode
	 *            字符集编码
	 * @return 布尔值
	 */
	public static boolean doCheck(String content, String sign, String publicKey, String encode) {
		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			byte[] encodedKey = RasKeyPairGenerator.decryptBASE64(publicKey);
			PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

			signature.initVerify(pubKey);
			signature.update(content.getBytes(encode));

			boolean bverify = signature.verify(RasKeyPairGenerator.decryptBASE64(sign));
			return bverify;

		} catch (Exception e) {
			e.printStackTrace();
		}

		return false;
	}

	public static boolean doCheck(String content, String sign, String publicKey) {
		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			byte[] encodedKey = RasKeyPairGenerator.decryptBASE64(publicKey);
			PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

			signature.initVerify(pubKey);
			signature.update(content.getBytes());

			boolean bverify = signature.verify(RasKeyPairGenerator.decryptBASE64(sign));
			return bverify;

		} catch (Exception e) {
			e.printStackTrace();
		}

		return false;
	}

5.结果
MD5 data:xYzo1AjfxwpdtwoQAZdkFA==
公钥加密:=�՝�+������0����i���O��:�oИF�mD�F�a(�f�w�9`J<�<�#�u������c����~�}���/LvV^��8n=��T�[�wO7IG�
?�-�/_E���f�t�w!��ZP��
@
公钥加密: base64编码:PYwR1Z2QK8CtGP7Z7hHRMKb9G62ZaZqJt0/O6zq2b9CYRq5tRPNGgWEoiGbTd445YEo8qjypI511
wvad4O/cY8rg/5N+AgyrfZaTri9MdlZeD/zyOG49ycJU1Fu4d083DElH0Ao/0hUtkC9fRe/9/maO
dIl3Ia/NWlAR6BmvCkA=

私钥解密:xYzo1AjfxwpdtwoQAZdkFA==
私钥解密: base64解码:xYzo1AjfxwpdtwoQAZdkFA==
签名 data:bPxKUUXH4Tf3QXavEly5F6gcA59DdvxIdba8Uhy5ihl3oMVhymzG/MWLM99dR3mBsNDl06XzqMr0
bvmFQvhyCkJEp9UfnRhtbdjSXTnWaUwSx7c7wwgSQQLEk5heajHaBhk204T/O6ftkAiJlwJIioYG
YwEjC0Wyj1evjXnJmbk=

验签成功

猜你喜欢

转载自blog.csdn.net/shy415502155/article/details/80662948