公钥与私钥机制属于非对称加密的范畴,非对称是相对于对称加密而言的,对称加密用于加密与解密的密钥是同一把,而非对称加密则用于加密与解密的密钥不相同,一个公开,称为公钥;一个保密,称为私钥,公钥与私钥必须成对出现,只有是配对的公钥与私钥才能用于加解密。公钥通过非安全通道发放,私钥则由发放者保留,公钥加密的数据,只能使用其配对的私钥对其解密;反之,私钥加密的数据,只可使用公钥对其解密。

ec java 私钥生公钥 java公钥和私钥_加密算法

 

对称加密出现后有效地提升的数据的安全性,但是由于加密与解密用的是同一把密钥,这样除了通信双方需要约定加密算法之外,数据发送方还需要将密钥发送给接收方,这为密钥的管理带来很大不便,为了弥补这一弱势,非对称加密算法就运而生。对于非对称加密来说,其公钥本身就是公开的,大家都知道,所以就不存在公钥管理的问题,只需要将私钥安全保存即可,这就为安全通信带来了极大的便利。

ec java 私钥生公钥 java公钥和私钥_加密算法_02

 

非对称加密算法与对象加密算法相比,密钥管理不复存在,在安全性上有着无法逾越的高度,但其加/解密效率却要比对称加密低得多,因此非对象加密算法往往应用在一些安全性要深圳市相当高的领域,如电子商务平台、银行网关、支付系统等。针对非对称加密算法低效的问题,很多情况下是将对称加密算法与非对称加密算法相结合,使用对称加密算法为数据加/解密,使用公钥与私钥为对象加密算法密钥加/解蜜。利用对称加密算法的高效性,加之非对象加密算法的密钥管理,提升整体加密系统的安全性。而且在算法的设计上,非对象加密算法对待加密数据长度还有着极为严苛的要求。例如,RSA算法要求待加密数据不得超过53个字节。基于上述原因,非对称加密算法主要用于交换对称加密算法与秘密密钥,而非数据交换。

 

所以一般我们的姓名,手机号,身份证号等信息可以把它进行非对称加密再存在我们的数据库里。

首先创建一个工具类RsaUtils.java,然后先写一个Rsa私钥(测试用,不写也可以)

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

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


public class RsaUtils {

    // Rsa 私钥MII
	public static String privateKey =                     
    "BVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY"
	+ "7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN"
    + "PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA"
	+ "kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow"
	+ "cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv"
	+ "DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh"
	+ "YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3" + "UP8iWi1Qw0Y=";

}

然后创建一下RSA密钥对对象

/**
	 * RSA密钥对对象
	 */
	public static class RsaKeyPair
	{
		private final String publicKey;
		private final String privateKey;

		public RsaKeyPair(String publicKey, String privateKey)
		{
			this.publicKey = publicKey;
			this.privateKey = privateKey;
		}

		public String getPublicKey()
		{
			return publicKey;
		}

		public String getPrivateKey()
		{
			return privateKey;
		}
	}

构建密钥对的方法

/**
	 * 构建RSA密钥对
	 *
	 * @return 生成后的公私钥信息
	 */
	public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException
	{
		KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
		keyPairGenerator.initialize(1024);
		KeyPair keyPair = keyPairGenerator.generateKeyPair();
		RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
		RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
		String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
		String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
		return new RsaKeyPair(publicKeyString, privateKeyString);
	}

公钥加密

/**
	 * 公钥加密
	 *
	 * @param publicKeyString 公钥
	 * @param text 待加密的文本
	 * @return 加密后的文本
	 */
	public static String encryptByPublicKey(String publicKeyString, String text) throws Exception
	{
		X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		byte[] result = cipher.doFinal(text.getBytes());
		return Base64.encodeBase64String(result);
	}

公钥解密

/**
	 * 公钥解密
	 *
	 * @param publicKeyString 公钥
	 * @param text 待解密的信息
	 * @return 解密后的文本
	 */
	public static String decryptByPublicKey(String publicKeyString, String text) throws Exception
	{
		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, publicKey);
		byte[] result = cipher.doFinal(Base64.decodeBase64(text));
		return new String(result);
	}

私钥加密

/**
	 * 私钥加密
	 *
	 * @param privateKeyString 私钥
	 * @param text 待加密的信息
	 * @return 加密后的文本
	 */
	public static String encryptByPrivateKey(String privateKeyString, String text) throws Exception
	{
		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
		byte[] result = cipher.doFinal(text.getBytes());
		return Base64.encodeBase64String(result);
	}

私钥解密

/**
	 * 私钥解密
	 *
	 * @param privateKeyString 私钥
	 * @param text 待解密的文本
	 * @return 解密后的文本
	 */
	public static String decryptByPrivateKey(String privateKeyString, String text) throws Exception
	{
		PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		byte[] result = cipher.doFinal(Base64.decodeBase64(text));
		return new String(result);
	}



	/**
	 * 私钥解密
	 *
	 * @param text 私钥
	 * @param text 待解密的文本
	 * @return 解密后的文本
	 */
	public static String decryptByPrivateKey(String text) throws Exception
	{
		return decryptByPrivateKey(privateKey, text);
	}

然后我们可以写个测试方法,测一下效果

public static void main(String[] args) throws Exception {
		RsaUtils.RsaKeyPair rsaKeyPair = null;
		try {
			rsaKeyPair = RsaUtils.generateKeyPair();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		System.out.println("公钥:");
		System.out.println(rsaKeyPair.getPublicKey());
		System.out.println("私钥:");
		System.out.println(rsaKeyPair.getPrivateKey());
		String phone = "4008123123";
		//公钥加密,私钥解密
		String phoneRsa = RsaUtils.encryptByPublicKey(rsaKeyPair.getPublicKey(), phone);
		System.out.println("加密后:"+phoneRsa);
		String phoneRsa2 = RsaUtils.decryptByPrivateKey(rsaKeyPair.getPrivateKey(), phoneRsa);
		System.out.println("解密后:"+phoneRsa2);
		//私钥加密,公钥解密
		String phoneRsa3 = RsaUtils.encryptByPrivateKey(rsaKeyPair.getPrivateKey(), phone);
		System.out.println("加密后:"+phoneRsa3);
		String phoneRsa4 = RsaUtils.decryptByPublicKey(rsaKeyPair.getPublicKey(), phoneRsa3);
		System.out.println("解密后:"+phoneRsa4);
	}

确实是非常的好用。