`
明子健
  • 浏览: 576591 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JAVA RSA 加密 解密 工具类 支持分片

    博客分类:
  • Java
阅读更多
package com.ming.util;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

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

/**
 * RSA加密,支持分片加密
 * <pre>
 * BCD码(Binary-Coded Decimal‎)亦称二进码十进数或二-十进制代码。
 * 用4位二进制数来表示1位十进制数中的0~9这10个数码。
 * 是一种二进制的数字编码形式,用二进制编码的十进制代码。
 * 注:日常所说的BCD码大都是指8421BCD码形式
 * @author Ming
 * 
 */
public class RSAUtil {
	/** 指定加密算法为RSA */
	private static String ALGORITHM = "RSA";
	/** 指定key的大小 */
	private static int KEYSIZE = 1024;
	/** 指定公钥存放文件 */
	private static String PUBLIC_KEY_FILE = "PublicKey";
	/** 指定私钥存放文件 */
	private static String PRIVATE_KEY_FILE = "PrivateKey";

	public static final String KEY_ALGORITHM = "RSA";
	public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

	/**
	 * 生成密钥对
	 */
	public static void generateKeyPair() throws Exception {
		if (getpublickey() == null || getprivatekey() == null) {
			/** RSA算法要求有一个可信任的随机数源 */
			SecureRandom sr = new SecureRandom();
			/** 为RSA算法创建一个KeyPairGenerator对象 */
			KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
			/** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
			kpg.initialize(KEYSIZE, sr);
			/** 生成密匙对 */
			KeyPair kp = kpg.generateKeyPair();
			/** 得到公钥 */
			Key publicKey = kp.getPublic();
			/** 得到私钥 */
			Key privateKey = kp.getPrivate();
			/** 用对象流将生成的密钥写入文件 */
			ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));
			ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));
			oos1.writeObject(publicKey);
			oos2.writeObject(privateKey);
			/** 清空缓存,关闭文件输出流 */
			oos1.close();
			oos2.close();
		}

	}

	/**
	 * 产生签名
	 * 
	 * @param data
	 * @param privateKey
	 * @return
	 * @throws Exception
	 */
	public static String sign(byte[] data, String privateKey) throws Exception {
		// 解密由base64编码的私钥
		byte[] keyBytes = decryptBASE64(privateKey);

		// 构造PKCS8EncodedKeySpec对象
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

		// KEY_ALGORITHM 指定的加密算法
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

		// 取私钥对象
		PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);

		// 用私钥对信息生成数字签名
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initSign(priKey);
		signature.update(data);

		return encryptBASE64(signature.sign());
	}

	/**
	 * 验证签名
	 * 
	 * @param data
	 * @param publicKey
	 * @param sign
	 * @return
	 * @throws Exception
	 */
	public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {

		// 解密由base64编码的公钥
		byte[] keyBytes = decryptBASE64(publicKey);

		// 构造X509EncodedKeySpec对象
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

		// KEY_ALGORITHM 指定的加密算法
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

		// 取公钥对象
		PublicKey pubKey = keyFactory.generatePublic(keySpec);

		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initVerify(pubKey);
		signature.update(data);

		// 验证签名是否有效
		return signature.verify(decryptBASE64(sign));
	}

	/**
	 * BASE64解密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptBASE64(String key) throws Exception {
		return (new BASE64Decoder()).decodeBuffer(key);
	}

	/**
	 * BASE64加密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encryptBASE64(byte[] key) throws Exception {
		return (new BASE64Encoder()).encodeBuffer(key);
	}

	/**
	 * 加密方法 source: 源数据
	 */
	public static String encrypt(String source) throws Exception {
		generateKeyPair();
		/** 将文件中的公钥对象读出 */
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
		Key key = (Key) ois.readObject();
		ois.close();
		/** 得到Cipher对象来实现对源数据的RSA加密 */
		Cipher cipher = Cipher.getInstance(ALGORITHM);
		cipher.init(Cipher.ENCRYPT_MODE, key);
		int MaxBlockSize = KEYSIZE / 8;
		int len = (MaxBlockSize - 11) / 8;
		String[] datas = splitString(source, len);
		StringBuffer mi = new StringBuffer();
		for (String s : datas) {
			mi.append(bcd2Str(cipher.doFinal(s.getBytes())));
		}
		return mi.toString();

	}

	/**
	 * 字符串分片
	 * 
	 * @param string
	 *            源字符串
	 * @param len
	 *            单片的长度(keysize/8)
	 * @return
	 */
	public static String[] splitString(String string, int len) {
		int x = string.length() / len;
		int y = string.length() % len;
		int z = 0;
		if (y != 0) {
			z = 1;
		}
		String[] strings = new String[x + z];
		String str = "";
		for (int i = 0; i < x + z; i++) {
			if (i == x + z - 1 && y != 0) {
				str = string.substring(i * len, i * len + y);
			} else {
				str = string.substring(i * len, i * len + len);
			}
			strings[i] = str;
		}
		return strings;
	}

	/**
	 * bcd 转 Str
	 * 
	 * @param bytes
	 * @return
	 */
	public static String bcd2Str(byte[] bytes) {
		char temp[] = new char[bytes.length * 2], val;
		for (int i = 0; i < bytes.length; i++) {
			val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
			temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');

			val = (char) (bytes[i] & 0x0f);
			temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
		}
		return new String(temp);
	}

	/**
	 * 解密
	 * 
	 * @param cryptograph
	 *            :密文
	 * @return 解密后的明文
	 * @throws Exception
	 */
	public static String decrypt(String cryptograph) throws Exception {
		generateKeyPair();
		/** 将文件中的私钥对象读出 */
		@SuppressWarnings("resource")
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
		Key key = (Key) ois.readObject();
		/** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
		Cipher cipher = Cipher.getInstance(ALGORITHM);
		cipher.init(Cipher.DECRYPT_MODE, key);
		int key_len = KEYSIZE / 8;
		byte[] bytes = cryptograph.getBytes();
		byte[] bcd = ASCII2BCD(bytes, bytes.length);
		StringBuffer sBuffer = new StringBuffer();
		byte[][] arrays = splitArray(bcd, key_len);
		for (byte[] arr : arrays) {
			sBuffer.append(new String(cipher.doFinal(arr)));
		}
		return sBuffer.toString();
	}

	/**
	 * ASCII 转 BCD
	 * 
	 * @param ascii
	 * @param asc_len
	 * @return
	 */
	public static byte[] ASCII2BCD(byte[] ascii, int asc_len) {
		byte[] bcd = new byte[asc_len / 2];
		int j = 0;
		for (int i = 0; i < (asc_len + 1) / 2; i++) {
			bcd[i] = asc2bcd(ascii[j++]);
			bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc2bcd(ascii[j++])) + (bcd[i] << 4));
		}
		return bcd;
	}

	/**
	 * asc转bcd
	 * 
	 * @param asc
	 * @return
	 */
	public static byte asc2bcd(byte asc) {
		byte bcd;

		if ((asc >= '0') && (asc <= '9'))
			bcd = (byte) (asc - '0');
		else if ((asc >= 'A') && (asc <= 'F'))
			bcd = (byte) (asc - 'A' + 10);
		else if ((asc >= 'a') && (asc <= 'f'))
			bcd = (byte) (asc - 'a' + 10);
		else
			bcd = (byte) (asc - 48);
		return bcd;
	}

	/**
	 * 字节数组分片
	 * 
	 * @param data
	 * @param len
	 * @return
	 */
	public static byte[][] splitArray(byte[] data, int len) {
		int x = data.length / len;
		int y = data.length % len;
		int z = 0;
		if (y != 0) {
			z = 1;
		}
		byte[][] arrays = new byte[x + z][];
		byte[] arr;
		for (int i = 0; i < x + z; i++) {
			arr = new byte[len];
			if (i == x + z - 1 && y != 0) {
				System.arraycopy(data, i * len, arr, 0, y);
			} else {
				System.arraycopy(data, i * len, arr, 0, len);
			}
			arrays[i] = arr;
		}
		return arrays;
	}

	/** 将文件中的公钥对象读出 */
	public static String getpublickey() {

		try {
			@SuppressWarnings("resource")
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
			Key key = (Key) ois.readObject();
			String publickey = encryptBASE64(key.getEncoded());
			return publickey;
		} catch (Exception e) {
			LogUtil.exception(e);
		}
		return null;
	}

	/** 将文件中的私钥对象读出 */
	public static String getprivatekey() {
		try {
			@SuppressWarnings("resource")
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
			Key key = (Key) ois.readObject();
			String privatekey = encryptBASE64(key.getEncoded());
			return privatekey;
		} catch (Exception e) {
			LogUtil.exception(e);
		}
		return null;
	}

	public static void main(String[] args) {
		try {
			String s = encrypt("allming.com");
			System.out.println("加密:"+s);
			System.out.println("解密:"+decrypt(s));

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

 

分享到:
评论

相关推荐

    JAVA中RSA加密解密工具类

    在Java编程语言中,RSA(Rivest-Shamir-...总结来说,RSA加密解密工具类在Java中是一个重要的安全组件,用于保护数据的安全传输和存储。理解并正确使用RSA算法及其相关的Java API对于开发安全的网络应用程序至关重要。

    C#RSA加密解密工具

    总的来说,C# RSA加密解密工具是一个实用的开发辅助工具,帮助开发者在C#环境中方便地实现RSA加密和解密操作,同时考虑到了与其他语言(如JavaScript和Java)的兼容性,提高了数据安全传输的灵活性和便利性。

    JAVA中RSA加密解密工具类加强版

    在"JAVA中RSA加密解密工具类加强版"这篇博客中,作者提供了一个加强版的RSA工具类,旨在简化RSA操作并提高效率。这个工具类通常包含以下功能: 1. **密钥对生成**:使用`java.security.KeyPairGenerator`类生成RSA...

    RSA加密解密验签工具类

    RSA加密解密验签工具类

    cpp-SwiftRSACrypto封装MIHCryptoSwift版本的RSA加密解密工具类

    总结,SwiftRSACrypto为Swift开发者提供了一个便捷的RSA加密解密工具,它通过封装Objc的MIHCrypto库,使得Swift项目能够利用RSA的强大功能,同时兼容Objective-C环境。在实际应用中,开发者应结合项目需求,合理使用...

    RSA工具类java加密解密非常全

    设计到的方法如下: DigitalSign init getInstance SignMsgByRelativePath SignMsgByInputStream signMsgByAbsolutePath verifyMsgByInputSteam verifyMsgByAbsolutePath verifyMsgByRelativePath ...

    unity工具类RSA加密和解密

    文件可能定义了一个名为UEncrypt的工具类,其中包含用于加密和解密的方法。这些方法可能接收字节数组或字符串作为输入,处理加密和解密的过程,并返回结果。 在实际应用中,注意以下几点: - 避免明文存储私钥,...

    Java实现RSA加解密工具类Demo

    Java实现RSA加解密工具类Demo是一个典型的非对称加密技术的应用示例,RSA是一种广泛使用的公开密钥加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出。它基于大数因子分解的困难性,提供了安全的...

    android工具类:基于javaBase64的加密解密工具类

    本文将详细介绍一个基于Java Base64的Android加密解密工具类,该工具类支持公钥加密和私钥解密,具有高度的解耦性,方便集成到项目中。 一、Base64加密解密基础 Base64是一种编码方式,它将任意二进制数据转换为可...

    RSA 加密 解密 C# Java 转化.zip

    可以实现C# Rsa加密(私钥加密、公钥解密、密钥格式转换、支持超大长度分段加密).net 转 java,java 转 .net 比如有一个开放平台:和目平台 亲测可用。他们就是只提供java的密钥,我已成功调用!如果有疑问需要...

    跨平台 AES MD5 ECC DES RSA 加密解密 支持 进度 支持多种编码.源码.FlyUtils_md5加密解密工具类

    在"Demos"目录下,可能包含了一些示例代码,用于演示如何使用"FlyUtils"库进行实际的加密解密操作,这对于初学者和开发者来说是非常有价值的资源,他们可以通过阅读和运行这些示例来快速理解和应用这些加密算法。...

    RSAUtils rsa加密解密java工具类

    RSAUtils rsa加密解密java工具类

    RSA加密解密示例工程

    在Yyspay这个子文件中,可能包含了实现上述功能的代码文件,如MainActivity.java(主界面的控制逻辑),RSAUtils.java(封装RSA加密解密的工具类),以及可能的布局文件和资源文件。开发者可以通过阅读和运行这些...

    Java RSA 加密/解密/签名 工具类

    Java RSA 加密/解密/签名工具类是Java开发中常用的一种安全技术实现,主要用于数据的保护和身份验证。RSA是一种非对称加密算法,基于大整数因子分解的困难性,提供了加密、解密以及数字签名的功能。下面将详细介绍...

    C# RSA加密、支持JAVA格式公钥私钥

    综上所述,这个C#项目旨在提供一个与Java平台兼容的RSA加密解密工具,方便跨平台的数据安全传输。开发人员可以利用这个工具包,使用C#进行RSA操作,同时处理来自Java环境的公钥和私钥。这在多语言协作或者混合系统...

    RSA2--》加签+加密+解密+验签

    本文将详细讲解RSA算法的加签、加密、解密以及验签的过程,结合Java语言来实现这一系列操作,并涉及到证书的使用。 首先,我们需要理解RSA算法的基本原理。RSA算法基于两个大素数的乘积难以分解这一数学难题,生成...

    RSACoder rsa加密解密java工具类,继承SecurityCoder

    RSACoder rsa加密解密java工具类,继承SecurityCoder

    C#RSA加密解密汇总

    总结来说,C#中的RSA加密解密是通过`RSACryptoServiceProvider`类实现的,它支持创建密钥对、加密和解密数据,以及密钥的存储和加载。在实际开发中,确保正确管理和保护私钥至关重要,因为它们是保障数据安全的关键...

    RSA加解密工具类

    自己封装的RSA加解密工具类,

    Java RSA 分段加密解密工具 .NET密钥转换

    采用Java Swing技术实现的一个小工具类 请在jre环境下使用

Global site tag (gtag.js) - Google Analytics