永远不要跟别人比幸运,我从来没想过我比别人幸运,我也许比他们更有毅力,在最困难的时候,他们熬不住了,我可以多熬一秒钟、两秒钟,甚至更久。

Java使用非对称加密算法RSA实现加密、解密

Java 新民 333℃ 已收录 2评论

在互联网项目、应用中,由于应用在外网的暴露,使得应用的安全要求更高,为了防止敏感数据被恶意劫取、恶意篡改。应用敏感数据必须加密,来保证对用户隐私、重要数据的安全性。下面来看看非对称加密RSA算法的实现:

 

    
	package file;

	import java.io.IOException;
	import java.security.InvalidKeyException;
	import java.security.KeyFactory;
	import java.security.KeyPair;
	import java.security.KeyPairGenerator;
	import java.security.NoSuchAlgorithmException;
	import java.security.PrivateKey;
	import java.security.PublicKey;
	import java.security.spec.InvalidKeySpecException;
	import java.security.spec.PKCS8EncodedKeySpec;
	import java.security.spec.X509EncodedKeySpec;

	import javax.crypto.BadPaddingException;
	import javax.crypto.Cipher;
	import javax.crypto.IllegalBlockSizeException;
	import javax.crypto.NoSuchPaddingException;

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

	public class RsaTest {
		
		/**
		 * 1、先初始化 KeyPairGenerator,并生成KeyPair,得到KeyPair
		 * @return
		 * @throws NoSuchAlgorithmException
		 */
		public static KeyPair getKeyPair() throws NoSuchAlgorithmException {
			KeyPairGenerator instance = KeyPairGenerator.getInstance("RSA");
			instance.initialize(1024);
			KeyPair keyPair = instance.generateKeyPair();
			return keyPair;
		}
		
		
		/**
		 * 2、通过KeyPair获得公钥
		 * 为了方便保存,通过Base64 编码将其转换为String类型
		 * @param keyPair
		 * @return
		 */
		public static String getPublicKey(KeyPair keyPair) {
			PublicKey publicKey = keyPair.getPublic();
			byte[] encoded = publicKey.getEncoded();
			BASE64Encoder base64Encoder = new BASE64Encoder();
			String encode = base64Encoder.encode(encoded);
			return encode;
		}
		
		
		/**
		 * 2、通过KeyPair获得私钥
		 * 为了方便保存,通过Base64 编码将其转换为String类型
		 * @param keyPair
		 * @return
		 */
		public static String getPrivateKey(KeyPair keyPair) {
			PrivateKey privateKey = keyPair.getPrivate();
			byte[] encoded = privateKey.getEncoded();
			BASE64Encoder base64Encoder = new BASE64Encoder();
			String encode = base64Encoder.encode(encoded);
			return encode;
		}
		
		
		/**
		 * 将String类型的公钥转换为PublicKey对象
		 * 先通过Base64解码,公钥需要转换成为X509EncodedKeySpec对象,然后通过KeyFactory生成PublicKey对象。
		 * @param publicKeyStr
		 * @return
		 * @throws IOException
		 * @throws NoSuchAlgorithmException
		 * @throws InvalidKeySpecException
		 */
		public static PublicKey string2PublicKey(String publicKeyStr) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
			BASE64Decoder base64Decoder = new BASE64Decoder();
			byte[] decodeBuffer = base64Decoder.decodeBuffer(publicKeyStr);
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodeBuffer);
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PublicKey publicKey = keyFactory.generatePublic(keySpec);
			return publicKey;
		}
		
		
		/**
		 * 将String类型的私钥转换为PrivateKey对象
		 * 先通过Base64解码,私钥需要转换成为PKCS8EncodedKeySpec对象,然后通过KeyFactory生成PrivateKey对象。
		 * @param privateKeyStr
		 * @return
		 * @throws IOException
		 * @throws NoSuchAlgorithmException
		 * @throws InvalidKeySpecException
		 */
		public static PrivateKey string2PrivateKey(String privateKeyStr) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
			BASE64Decoder base64Decoder = new BASE64Decoder();
			byte[] decodeBuffer = base64Decoder.decodeBuffer(privateKeyStr);
			PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodeBuffer);
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
			return privateKey ;
		}
		
		
		/**
		 * 使用公钥加密
		 * 首先获得RSA算法的Cipher实例,然后传入加密模式Cipher.ENCRYPT_MODE和公钥PublicKey类的实例进行初始化,
		 * 通过doFinal方法获得加密字节流
		 * @param content
		 * @param publicKey
		 * @return
		 * @throws NoSuchAlgorithmException
		 * @throws NoSuchPaddingException
		 * @throws InvalidKeyException
		 * @throws IllegalBlockSizeException
		 * @throws BadPaddingException
		 */
		public static byte[] publicEncrypt(byte[] content,PublicKey publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE,publicKey);
			byte[] bytes = cipher.doFinal(content);
			return bytes;
		}
		
		/**
		 * 使用私钥解密
		 * 首先获得RSA算法的Cipher实例,然后传入解密模式Cipher.DECRYPT_MODE和PrivateKey类的实例,
		 * 通过doFinal方法获得解密字节流
		 * @param content
		 * @param privateKey
		 * @return
		 * @throws NoSuchAlgorithmException
		 * @throws NoSuchPaddingException
		 * @throws InvalidKeyException
		 * @throws IllegalBlockSizeException
		 * @throws BadPaddingException
		 */
		public static byte[] privateDecrypt(byte[] content,PrivateKey privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, privateKey);
			byte[] bytes = cipher.doFinal(content);
			return bytes;
		}
		
		public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException, IOException {
			
			KeyPair keyPair = RsaTest.getKeyPair();
			String publicKey = RsaTest.getPublicKey(keyPair);
			PublicKey publicKeyObj = RsaTest.string2PublicKey(publicKey);
			
			
			String privateKey = RsaTest.getPrivateKey(keyPair);
			PrivateKey privateKeyObj = RsaTest.string2PrivateKey(privateKey);
			
			
			String resource = "你好,这是RSA算法";
			
			byte[] publicEncrypt = RsaTest.publicEncrypt(resource.getBytes("utf-8"), publicKeyObj);
			System.out.println("加密后的字符串:"+new String(publicEncrypt,"utf-8"));
			
			byte[] decode = RsaTest.privateDecrypt(publicEncrypt, privateKeyObj);
			System.out.println("解密后的字符串:"+new String(decode,"utf-8"));
			
			
			System.out.println("私钥:"+privateKey);
			System.out.println("公钥:"+publicKey);
		}

	}

如果使用1024初始化KeyPairGenerator,RSA加密后的密文长度为1024位,即128个字节,此时明文的最大长度不能超过117个字节,超过117个字节要使用2048的keysize来初始化KeyPairGenerator,超过245个字节,则需要使用更高位数的keysize,RSA的位数越高,其产生秘钥及加密、解密的速度越慢。这是基于大素数非对称加密的缺陷。

本站文章如未注明,均为原创丨本网站采用BY-NC-SA协议进行授权,转载请注明转自:http://www.snowruin.com/?p=1730
喜欢 (1)or分享 (0)
发表我的评论
取消评论
表情 代码 贴图 加粗 链接 私信 删除线 签到

Hi,请填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(2)条精彩评论。
  1. 炎热夏天,闲来无事,拜读博客,消暑解闷!
    9482018-06-21 17:41 回复| Google Chrome 14.0.802.30| Windows 7
  2. 第一次看,感觉还挺新鲜!
    kitty232018-06-17 17:08 回复| Google Chrome 14.0.802.30| Windows 7