加密解密算法java实现(3)—RSA

原创 2016年12月22日 15:25:09

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.dzh</groupId>
  <artifactId>encrypt-util</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>encrypt-util</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
    	<groupId>commons-codec</groupId>
	    <artifactId>commons-codec</artifactId>
	    <version>1.9</version>
	</dependency>
	<dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.55</version>
<!--         <scope>provided</scope> -->
    </dependency>
  </dependencies>
</project>

关于下面的代码的注意点:

此工具类能使用指定的字符串,每次生成相同的公钥和私钥且在linux和windows密钥也相同;相同的原文和密钥生成的密文相同。

如果需要每次生成不同的密钥或者生成不同的密文,代码要做修改。

下面的代码用到了我写的BASE64加密,参考《加密解密算法java实现(1)—BASE64》

java代码如下:

package com.dzh.rsa;

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
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;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.dzh.base64.BASE64Util;

/**
 * RSA加密解密
 * 此工具类能使用指定的字符串,每次生成相同的公钥和私钥且在linux和windows密钥也相同;相同的原文和密钥生成的密文相同
 */
public class RSAUtil {
	private static final String ALGORITHM_RSA = "RSA";
	private static final String ALGORITHM_SHA1PRNG = "SHA1PRNG";
	private static final int KEY_SIZE = 1024;
	private static final String PUBLIC_KEY = "RSAPublicKey";
	private static final String PRIVATE_KEY = "RSAPrivateKey";
	private static final String TRANSFORMATION = "RSA/None/NoPadding";
	
	/**
	 * 解密
	 * 用私钥解密,解密字符串,返回字符串
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String decryptByPrivateKey(String data, String key) throws Exception {
		return new String(decryptByPrivateKey(BASE64Util.decodeToByte(data), key));
	}
	
	/**
	 * 加密
	 * 用公钥加密,加密字符串,返回用base64加密后的字符串
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encryptByPublicKey(String data, String key) throws Exception {
		return encryptByBytePublicKey(data.getBytes(), key);
	}
	/**
	 * 加密
	 * 用公钥加密,加密byte数组,返回用base64加密后的字符串
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encryptByBytePublicKey(byte[] data, String key) throws Exception {
		return BASE64Util.encodeByte(encryptByPublicKey(data, key));
	}
	
	/**
	 * 解密
	 * 用私钥解密
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
		byte[] keyBytes = BASE64Util.decodeToByte(key);//对私钥解密
		/*取得私钥*/
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
		/*对数据解密*/
		Cipher cipher = Cipher.getInstance(TRANSFORMATION, new BouncyCastleProvider());//相同的原文、公钥能生成相同的密文。如果使用Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//相同的原文、公钥生成的密文不同
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		
		return cipher.doFinal(data);
	}
	
	/**
	 * 加密
	 * 用公钥加密
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {
		byte[] keyBytes = BASE64Util.decodeToByte(key);//对公钥解密
		/*取得公钥*/
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
		Key publicKey = keyFactory.generatePublic(x509KeySpec);
		/*对数据加密*/
		Cipher cipher = Cipher.getInstance(TRANSFORMATION, new BouncyCastleProvider());//相同的原文、公钥能生成相同的密文。如果使用Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());//相同的原文、公钥生成的密文不同
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		
		return cipher.doFinal(data);
	}
	
	/**
	 * 取得私钥
	 * @param keyMap
	 * @return
	 */
	public static String getPrivateKey(Map<String, Object> keyMap) {
		Key key = (Key) keyMap.get(PRIVATE_KEY);
		return BASE64Util.encodeByte(key.getEncoded());
	}
	
	/**
	 * 取得公钥
	 * @param keyMap
	 * @return
	 */
	public static String getPublicKey(Map<String, Object> keyMap) {
		Key key = (Key) keyMap.get(PUBLIC_KEY);
		return BASE64Util.encodeByte(key.getEncoded());
	}
	
	/**
	 * 初始化公钥和私钥
	 * @param seed
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> initKey(String seed) throws Exception {
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);
		SecureRandom random = SecureRandom.getInstance(ALGORITHM_SHA1PRNG);//如果使用SecureRandom random = new SecureRandom();//windows和linux默认不同,导致两个平台生成的公钥和私钥不同
		random.setSeed(seed.getBytes());//使用种子则生成相同的公钥和私钥
		keyPairGen.initialize(KEY_SIZE, random);
		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;
	}
	
	/**
	 * 使用示例
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		String source = "12dfefDKLJKLKL464d中文f465as43f1a3 f46e353D1F34&*^$E65F46EF43456abcd54as56f00ef";//原文
		String seed = "abc123";//种子
		
		System.out.println("原文:\n" + source);
		Map<String, Object> keyMap = RSAUtil.initKey(seed);//初始化密钥
		String publicKey = RSAUtil.getPublicKey(keyMap);//公钥
		String privateKey = RSAUtil.getPrivateKey(keyMap);//私钥
		System.out.println("公钥:\n" + publicKey);
		System.out.println("私钥:\n" + privateKey);
		String encodedStr = RSAUtil.encryptByPublicKey(source, publicKey);//加密
		System.out.println("密文:\n" + encodedStr);
		String decodedStr = RSAUtil.decryptByPrivateKey(encodedStr, privateKey);//解密
		System.out.println("解密后的结果:\n" + decodedStr);
	}
}

按照示例使用即可

java RSA加密解密实现

该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar 下载地址:http://download.csdn.net/detail/centralperk/5025...
  • centralperk
  • centralperk
  • 2013年01月24日 16:28
  • 64461

Java中利用RSA算法进行加密解密

首先需要两个工具类 package cnsts.common.utils; import java.io.BufferedReader; import java.io.ByteArrayOutpu...
  • draven1122
  • draven1122
  • 2017年02月15日 17:08
  • 6750

Java非对称加密算法--RSA

非对称加密的特点是有两把钥匙,公钥和私钥。公钥加密只能私钥解密;私钥加密只能公钥解密。 在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E...
  • zhangzeyuaaa
  • zhangzeyuaaa
  • 2015年11月23日 14:18
  • 1954

RSA加密算法java简单实现

简单完整的代码,通过这个代码你将对RSA加密算法在Java中的实现方法有一个初步的了解,这个类,你可以直接使用,水平高的,就自己修改完善下代码。...
  • houzuoxin
  • houzuoxin
  • 2014年09月04日 16:44
  • 27905

RSA加密算法的java实现

最近有一个外部合作项目要求在数据传输过程中使用RSA加密算法对数据进行加密,所以需要编写一个加解密的工具类,因为对方不是java语言,所以是各自实现的这个工具,本文主要讨论实现以及双方调试过程中的一些...
  • cz0217
  • cz0217
  • 2017年11月02日 16:53
  • 950

java RSA非对称加密详解

简介RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年首次公布,当时...
  • a394268045
  • a394268045
  • 2016年08月17日 17:26
  • 5457

RSA加密算法Java应用实例

该算法于1977年由美国麻省理工学院MIT(Massachusetts Institute of Technology)的Ronal Rivest,Adi Shamir和Len Adleman三位年轻...
  • zeng622peng
  • zeng622peng
  • 2010年10月21日 16:47
  • 26253

RSA加密算法-Java实现

package test;import java.io.*;import java.security.*;import javax.crypto.*;import javax.crypto.spec....
  • kj619899271
  • kj619899271
  • 2011年03月03日 17:06
  • 14943

MD5和RSA加密算法Java完成实现

  • 2014年05月21日 22:29
  • 1.32MB
  • 下载

Java使用RSA加密解密签名及校验

由于项目要用到非对称加密解密签名校验什么的,于是参考《Java加密解密的艺术》写一个RSA进行加密解密签名及校验的Demo,代码很简单,特此分享!RSA加密解密类:package com.ihep; ...
  • wangqiuyun
  • wangqiuyun
  • 2014年12月25日 11:37
  • 114167
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:加密解密算法java实现(3)—RSA
举报原因:
原因补充:

(最多只允许输入30个字)