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加密解密工具类
RSA加密解密验签工具类
Java RSA 加密/解密/签名 工具类 Java RSA 加密/解密/签名 工具类 Java RSA 加密/解密/签名 工具类
C#RSA加密解密工具,可以生成公钥和私钥,可以生成PKCS1公钥,PKCS8私钥。适用于js加密,C#解密,java解密。
设计到的方法如下: DigitalSign init getInstance SignMsgByRelativePath SignMsgByInputStream signMsgByAbsolutePath verifyMsgByInputSteam verifyMsgByAbsolutePath verifyMsgByRelativePath ...
unity工具类RSA加密和解密
RSA加密加签工具类,支持公钥私钥加签验签,数据分块加密解密
RSAUtils rsa加密解密java工具类
跨平台 AES MD5 ECC DES RSA 加密解密 支持 进度 支持多种编码.源码.FlyUtils
RSACoder rsa加密解密java工具类,继承SecurityCoder
根据证书私钥加签---》RSA公钥加密--》RSA私钥解密---》证书公钥验签
spring框架中关于RSA sha-256加密解密,加签验签工具类
自己封装的RSA加解密工具类,
这个RSA加解密的Demo是我从别的地方花了好多金币下载的,希望对大家有帮助,资源共享嘛。
采用Java Swing技术实现的一个小工具类 请在jre环境下使用
AES RSA 加密解密工具类以及RSA 签名 和验证签名等方法以及自动生成成对的RSA 公私钥
非常实用的rsa加解密工具类,加签验签,拿过去就能用,包含测试代码
YYRSACrypto 的 Swift 版本,基于 Objc 的 MIHCrypto 封装,所以是一个混编的工具类
RSA加密工具类,公私钥加解密、公私钥验签,读取私钥.ps8方法。
博客地址 http://blog.csdn.net/sbsujjbcy/article/details/46873403