文档章节

RSA加解密-java

c
 chenjisi
发布于 2017/03/27 19:11
字数 915
阅读 10
收藏 0

RSAUtil.java

import java.io.ByteArrayOutputStream;
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.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
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 org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

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

@SuppressWarnings("restriction")
public class RSAUtil {

	private static final Logger logger = Logger.getLogger(IniCreate.class);
	/**
	 * 公钥
	 */
	private static RSAPrivateKey privateKey = null;
	/**
	 * 私钥
	 */
	private static RSAPublicKey publicKey = null;
	/**
	 * base64加密后的公钥
	 */
	private static String publicKeyBase64 = null;
	/**
	 * base64加密后的公钥-- openssl版本(加头)
	 */
	private static String publicKeyBase64ForOpenssl = null;
	/**
	 * RSA最大加密明文大小
	 */
	private static final int MAX_ENCRYPT_BLOCK = 117;
	/**
	 * RSA最大解密密文大小
	 */
	private static final int MAX_DECRYPT_BLOCK = 128;
	/**
	 * openssl publicKey头
	 */
	private static final String BEGIN = "-----BEGIN PUBLIC KEY-----";
	/**
	 * openssl publicKey尾
	 */
	private static final String END = "-----END PUBLIC KEY-----";
	/**
	 * openssl publicKey尾
	 */
	private static final String separator = System.getProperty("line.separator");

	// 初始化生成公钥和私钥
	public static void generateKey() throws NoSuchAlgorithmException {
		// 生成公钥和私钥对,基于RSA算法生成对象
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");

		// 初始化密钥对生成器,密钥大小为1024位
		keyPairGen.initialize(1024);

		// 生成一个密钥对,保存在keyPair中
		KeyPair keyPair = keyPairGen.generateKeyPair();

		// 得到私钥和公钥
		privateKey = (RSAPrivateKey) keyPair.getPrivate();
		publicKey = (RSAPublicKey) keyPair.getPublic();
		BASE64Encoder encode = new BASE64Encoder();
		// 将byte[]转换为base64
		publicKeyBase64 = encode.encode(publicKey.getEncoded());
		// privateKeyBase64=encode.encode(privateKey.getEncoded());
		publicKeyBase64ForOpenssl = BEGIN + separator + publicKeyBase64 + separator + END;
	}

	// Base64加密
	public static String encodeByBase64(byte[] content) {
		BASE64Encoder encode = new BASE64Encoder();
		return encode.encode(content);
	}

	// Base64解密
	public static byte[] decodeByBase64(String content) throws IOException {
		BASE64Decoder decode = new BASE64Decoder();
		// 将base64转换为byte[]
		return decode.decodeBuffer(content);
	}

	// 通过私钥byte[]将私有钥还原,适用于RSA算法
	public static RSAPublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PublicKey publicKey = keyFactory.generatePublic(keySpec);
		return (RSAPublicKey) publicKey;
	}

	// 通过私钥byte[]将公钥还原,适用于RSA算法
	public static RSAPrivateKey getPrivateKey(byte[] keyBytes)
			throws NoSuchAlgorithmException, InvalidKeySpecException {
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		return (RSAPrivateKey) privateKey;
	}

	// RSA加密
	public static byte[] encrypt(RSAPublicKey key, byte[] srcBytes) throws InvalidKeyException,
			NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
		if (null == key) {
			logger.error("[RSAUtil] decrypt RSAPublicKey is null");
			throw new NullPointerException("[RSAUtil] encrypt RSAPublicKey is null");
		}
		// Cipher负责完成加密或解密工作,基于RSA
		Cipher cipher = Cipher.getInstance("RSA");
		// 根据公钥,对Cipher对象进行初始化
		cipher.init(Cipher.ENCRYPT_MODE, key);
		int inputLen = srcBytes.length;  
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        int offSet = 0;  
        byte[] cache;  
        int i = 0;  
        // 对数据分段加密  
        while (inputLen - offSet > 0) {  
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {  
                cache = cipher.doFinal(srcBytes, offSet, MAX_ENCRYPT_BLOCK);  
            } else {  
                cache = cipher.doFinal(srcBytes, offSet, inputLen - offSet);  
            }  
            out.write(cache, 0, cache.length);  
            i++;  
            offSet = i * MAX_ENCRYPT_BLOCK;  
        }  
        byte[] encryptedData = out.toByteArray();  
        try {
			out.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
        return encryptedData;  	
	}

	// RSA解密
	public static byte[] decrypt(RSAPrivateKey key, byte[] encBytes) throws InvalidKeyException,
			NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
		if (null == key) {
			logger.error("[RSAUtil] decrypt RSAPrivateKey is null");
			throw new NullPointerException("[RSAUtil] decrypt RSAPrivateKey is null");
		}
		Cipher cipher = Cipher.getInstance("RSA");
		// 根据私钥对Cipher对象进行初始化
		cipher.init(Cipher.DECRYPT_MODE, key);
		int inputLen = encBytes.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段解密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
				cache = cipher.doFinal(encBytes, offSet, MAX_DECRYPT_BLOCK);
			} else {
				cache = cipher.doFinal(encBytes, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_DECRYPT_BLOCK;
		}
		byte[] decryptedData = out.toByteArray();
		try {
			out.close();
		} catch (IOException e) {
			logger.error("[RSAUtil] decrypt RSAPrivateKey out.toByteArray() error", e);
			e.printStackTrace();
		}
		return decryptedData;
	}

	public static RSAPublicKey getPublicKey() {
		return publicKey;
	}

	public static String getPublicKeyBase64() {
		return publicKeyBase64;
	}

	public static RSAPrivateKey getPrivateKey() {
		return privateKey;
	}

	public static String getPublicKeyBase64ForOpenssl() {
		return publicKeyBase64ForOpenssl;
	}

	@SuppressWarnings("unused")
	public static void main(String[] args) {
		try {
			// 生成公钥和私钥
			generateKey();

			// 公钥转成Base64
			String publicKeyBase64 = encodeByBase64(publicKey.getEncoded());
			System.out.println("publicKeyBase64=" + publicKeyBase64);
			// 私钥转成Base64
			String privateKeyBase64 = encodeByBase64(publicKey.getEncoded());
			System.out.println("privateKeyBase64=" + privateKeyBase64);

			// Base64公钥转回字节数组
			byte[] publicKeyByte = decodeByBase64(publicKeyBase64);
			System.out.println("publicKeyByte=" + publicKeyByte);

			// Base64私钥转回字节数组
			byte[] privateKeyByte = decodeByBase64(privateKeyBase64);
			System.out.println("privateKey=" + privateKey);

			// 转回公钥对象
			RSAPublicKey publickey = getPublicKey(publicKeyByte);
			// 加密
			byte[] reslutbyte = encrypt(publickey, "调度,四十多分".getBytes());
			// 密文转成Base64
			String messageStr = encodeByBase64(reslutbyte);
			// Base64密文转回byte
			byte[] messageByte = decodeByBase64(messageStr);
			System.out.println("messageByte=" + new String(messageByte));
			// 解密
			byte[] resultByte = decrypt(privateKey, messageByte);
			System.out.println("reslut=" + new String(resultByte, "UTF-8"));
			String aaa = "{\"username\":\"xxxx1\",\"password\":\"xxxx2\"}";
			JSONObject requestParam = JSON.parseObject(aaa);
			String username = requestParam.getString("username");
			String password = requestParam.getString("password");
			System.out.println("username=" + username);
			System.out.println("password=" + password);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

接口调用:基于springmvc

/**
	 * 获取publicKey
	 * 
	 * @since 2016-4-20
	 * @author chenjisi
	 * @version 1.0
	 * @param request,response
	 * @return void
	 */
	@RequestMapping(value = "/getPublicKey", method = RequestMethod.GET)
	public void getPublicKey(HttpServletRequest request, HttpServletResponse response) {
		SrvRemain srvRemain = null;
		if (null == RSAUtil.getPublicKey()) {
			try {
				RSAUtil.generateKey();
			} catch (NoSuchAlgorithmException e) {
				logger.error("RSAUtil.getPublicKey() error", e);
				printWriter(response, e.getMessage);
				return;
			}
		}
		String fileName = "publicKey.key";
		response.setHeader("content-disposition", "attachment;filename=" + fileName);
		try {
			response.getWriter().write(RSAUtil.getPublicKeyBase64ForOpenssl());
		} catch (IOException e) {
			logger.error("getPublicKey IOException", e);
                        response.getWriter().write(e.getMessage);
		}
	}

© 著作权归作者所有

c

chenjisi

粉丝 8
博文 1
码字总数 915
作品 0
福州市
私信 提问
Android外部文件加解密及应用实践

有这样的应用场景,当我们把一些重要文件放到asset文件夹中时,把.apk解压是可以直接拿到这个文件的,一些涉及到重要信息的文件我们并不想被反编译拿去,这个时候需要先对文件进行加密,然后...

C6C
2018/05/08
0
0
.NET和java的RSA互通,仅此而已

.NET和java的RSA互通,仅此而已 在开始这篇文章之前,先请读者朋友阅读老唐的这两篇文章: 1、Java与.Net环境下RSA加密解密交互不成功的问题解决 2、Java与.Net环境下RSA加密解密交互不成功的...

lubiaopan
2011/03/09
0
0
浅析RSA公钥密码以及使用Java自带API实现RSA的密钥生成和加解密

RSA是目前最流行的非对称密码,目前广泛应用在数字签名,数字证书上。 那么什么是非对称密码呢?就是给明文加密的密钥和给密文解密的密钥是不一样的。其中,对外暴露的是公钥,自己保留的是私...

Lunqi
2015/07/15
1K
1
Java结合keytool实现非对称加密和解密

原文出处:王洁 参考:Java结合keytool实现非对称签名与验证 那一篇讲签名,这一篇将加密解密。在Java安全体系中,签名属于JAAS模块,加解密属于JCE模块。 keytool的使用 keytool是JDK自带的...

王洁
2018/08/08
0
0
关于一个RSA跨语言(java 和py)的加密解密操作

现在有一个需求,java平台提供接口,python平台调用接口,中间用到rsa进行接口的加密解密。java服务端的rsa加密操作已经完成,返回一个16进制的字符串给python平台,但是在python进行私钥解密...

我亦暖心丶
2018/07/17
828
1

没有更多内容

加载失败,请刷新页面

加载更多

mysql-connector-java升级到8.0后保存时间到数据库出现了时差

在一个新项目中用到了新版的mysql jdbc 驱动 <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.18</version> ......

ValSong
43分钟前
5
0
Spring Boot 如何部署到 Linux 中的服务

打包完成后的 Spring Boot 程序如何部署到 Linux 上的服务? 你可以参考官方的有关部署 Spring Boot 为 Linux 服务的文档。 文档链接如下: https://docs.ossez.com/spring-boot-docs/docs/r...

honeymoose
45分钟前
5
0
Spring Boot 2 实战:使用 Spring Boot Admin 监控你的应用

1. 前言 生产上对 Web 应用 的监控是十分必要的。我们可以近乎实时来对应用的健康、性能等其他指标进行监控来及时应对一些突发情况。避免一些故障的发生。对于 Spring Boot 应用来说我们可以...

码农小胖哥
今天
6
0
ZetCode 教程翻译计划正式启动 | ApacheCN

原文:ZetCode 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 学习资源 贡献指南 本项目需要校对,欢迎大家提交 Pull Request。 ...

ApacheCN_飞龙
今天
4
0
CSS定位

CSS定位 relative相对定位 absolute绝对定位 fixed和sticky及zIndex relative相对定位 position特性:css position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则...

studywin
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部