主要参考: http://www.blogjava.net/icewee/archive/2012/05/19/378570.html
基于以上代码汇总而成:
实现效果
1生成公钥\私钥. 保存在内存/文件中.
2从文件或者内存中读取公钥私钥.加密.
3加密后传输过程中,使用hex加密.
-------------------------------------------------------------------------------------
Coder 基础加密组件
package com.test; import java.security.MessageDigest; import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec; import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; /**
* 基础加密组件
* @author 梁栋
* @version 1.0
* @since 1.0
*/
public abstract class Coder {
public static final String KEY_SHA = "SHA";
public static final String KEY_MD5 = "MD5"; /**
* MAC算法可选以下多种算法
*
* <pre>
* HmacMD5
* HmacSHA1
* HmacSHA256
* HmacSHA384
* HmacSHA512
* </pre>
*/
public static final String KEY_MAC = "HmacMD5"; /**
* 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);
} /**
* MD5加密
*
* @param data
* @return
* @throws Exception
*/
public static byte[] encryptMD5(byte[] data) throws Exception { MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
md5.update(data); return md5.digest(); } /**
* SHA加密
*
* @param data
* @return
* @throws Exception
*/
public static byte[] encryptSHA(byte[] data) throws Exception { MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
sha.update(data); return sha.digest(); } /**
* 初始化HMAC密钥
*
* @return
* @throws Exception
*/
public static String initMacKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC); SecretKey secretKey = keyGenerator.generateKey();
return encryptBASE64(secretKey.getEncoded());
} /**
* HMAC加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptHMAC(byte[] data, String key) throws Exception { SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey); return mac.doFinal(data); }
}
RSACoder RSA加密组件
package com.test; 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.Signature;
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; /**
* RSA安全编码组件
*
* @author 梁栋
* @version 1.0
* @since 1.0
*/
public abstract class RSACoder extends Coder {
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; private static final String PUBLIC_KEY = "RSAPublicKey";
private static final String PRIVATE_KEY = "RSAPrivateKey"; /**
* 用私钥对信息生成数字签名
*
* @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 校验成功返回true 失败返回false
* @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));
} /**
* 解密<br>
* 用私钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key); // 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data);
} /**
* 解密<br>
* 用公钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key); // 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data);
} /**
* 加密<br>
* 用公钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String key)
throws Exception {
// 对公钥解密
byte[] keyBytes = decryptBASE64(key); // 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data);
} /**
* 加密<br>
* 用私钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key); // 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data);
} /**
* 取得私钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded());
} /**
* 取得公钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return encryptBASE64(key.getEncoded());
} /**
* 初始化密钥
*
* @return
* @throws Exception
*/
public static Map<String, Object> initKey() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024); 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;
}
}
base64Util base加密解密工具类
package com.test; import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; /**
* BASE64 严格地说,属于编码格式,而非加密算法
* Base64被定义为:Base64内容传送编码被设计用来
* 把任意序列的8位字节描述为一种不易被人直接识别的形式。
* 常见于邮件、http加密,截取http信息,你就会发现登录操
* 作的用户名、密码字段通过BASE64加密的。
* @author Z10
* @time 2014-7-4 上午10:41:11
*/
public class base64Util { public static void main(String[] args) {
String str ="我是James. 今年1岁。";
// String str ="Ilovepolly";
System.out.println("加密前"+str);
String enStr = null;
String deStr = null;
String deStr2 = null;
try {
enStr = base64Util.encryptBASE64(str.getBytes());
deStr = (base64Util.decryptBASE64(enStr)).toString(); //错误用法无法将byte转为string
deStr2 = new String(base64Util.decryptBASE64(enStr));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("加密后"+enStr);
System.out.println("解密后"+deStr);
System.out.println("解密后"+deStr2); } /**
* 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);
}
}
十六进制/2进制转换工具类 hex-byte
MyUtils
package com.test.util; import java.io.UnsupportedEncodingException; public abstract class MyUtils { public static char[] hex={'0','1','2','3',
'4','5','6','7',
'8','9','a','b',
'c','d','e','f',}; public static String byteToHex(byte[] encode){ StringBuffer sb = new StringBuffer(); for(int i=0;i<encode.length;i++){
sb.append(hex[(encode[i]>>>4) & 0xF]);//按照字节序列,从高位到低位进行解析
sb.append(hex[encode[i] & 0xF]);
} return sb.toString();
} public static byte[] hexToByte(String strIn) throws Exception{ byte[] buf=new byte[strIn.length()/2]; for(int i=0;i<strIn.length();i=i+2){
String s = strIn.substring(i, i+2);
buf[i/2]= (byte) Integer.parseInt(s,16);
} return buf;
// System.out.println(strIn.length());
// byte[] arrB = strIn.getBytes("UTF-8");
// int iLen = arrB.length;
//
// // 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
// byte[] arrOut = new byte[iLen / 2];
// System.out.println(arrOut.length);
// for (int i = 0; i < iLen; i = i + 2) {
// String strTmp = new String(arrB, i, 2, "UTF-8");
// arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
// }
// return arrOut;
} }
实际RSA加密解密工具类RSAUtils_V2
package com.test.Rsa;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
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.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException; import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import com.test.util.RSACoder; /** *//**
* <p>
* RSA公钥/私钥/签名工具包 v2 UPDATE BY ZYL
* </p>
* <p>
* 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)
* </p>
* <p>
* 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
* </p>
* <P>
* 版本2更新变化:
* 1原版本密钥创建后保存在内存map中,新版本密钥创建后保存为public.key,private.key的功能(base64解码后保存).
* 2为保证生成文件的密钥内容可以显示并缩短加密后的长度,对需加密内容进行hex(16进制转换)处理后再加密.
* 即
* </P>
*
* @author IceWee
* @date 2012-4-26
* @version 1.0
*/
public class RSAUtils_V2 { /** *//**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA"; /** *//**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** *//**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey"; /** *//**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey"; /** *//**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117; /** *//**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128; /** *//**
* <p>
* 生成密钥对(公钥和私钥)
* </p>
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);//"RSA"
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();//Generates a key pair 生成公钥私钥.
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;
} /**
* 将公钥私钥(默认base64加密)并转为公钥/私钥字符串还原为对应公钥/私钥
* by Z10
* @param keyType (publicKey / privateKey)
* @param keystr
* @return
* @throws Exception
*/
public Key getKeybyKeyStr(String keyType,String keystr) throws Exception{
if(keyType==null||!keyType.equals("")){
throw new Exception("keyType can not be null");
}
//需要返回公钥
if(keyType.equals(keyType)){
byte[] keyBytes = Base64Utils.decode(keystr);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
return publicK;
}
//需要返回私钥
else if(keyType.equals("privateKey")){
byte[] keyBytes = Base64Utils.decode(keystr);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
return privateK;
}else{
throw new Exception("keyType'value is incorrect");
}
} /**
* 根据传入的key文件名生成对应key文件. by zyl
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public static Map<String, Object> getKeyByFile() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException{
Map<String, Object> keyMap = new HashMap<String, Object>(2);
FileInputStream fin = new FileInputStream(new File("public.key"));
byte[] buf = new byte[fin.available()];
fin.read(buf);
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decode(new String(buf)));
// 构建key工厂
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// 获取到完整的publickey对象
PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
FileInputStream fin2 = new FileInputStream(new File("private.key"));
byte[] buf2=new byte[fin2.available()];
fin2.read(buf2);
KeyFactory keyFactory2 = KeyFactory.getInstance("RSA");
@SuppressWarnings("static-access")
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(new Base64().decode(new String(buf2)));
// 获取到完整的privatekey对象
PrivateKey privateKey = keyFactory2.generatePrivate(privateKeySpec);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
} /**
* 生成密钥文本文件
* @throws Exception
*/
public static void createKeyFile(Map<String, Object> keyMap) throws Exception{
//生成公钥
String publicKey_Str=RSACoder.getPublicKey(keyMap);
byte[] bytes1=publicKey_Str.getBytes("UTF-8");
Base64Utils.byteArrayToFile(bytes1, "public.key"); //生成私钥
String privateKey_Str=RSACoder.getPrivateKey(keyMap);
byte[] bytes2=privateKey_Str.getBytes("UTF-8");
Base64Utils.byteArrayToFile(bytes2, "private.key"); } /** *//**
* <p>
* 用私钥对信息生成数字签名
* </p>
*
* @param data 已加密数据
* @param privateKey 私钥(BASE64编码)
*
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return Base64Utils.encode(signature.sign());
} /** *//**
* 校验数字签名
* </p>
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
* @return
* @throws Exception
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64Utils.decode(sign));
} /**
*私钥解密 by zyl
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, Key privateKey)throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
} /** *//**
* 私钥解密
* </p>
* @param encryptedData 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
} /** *//**
* 公钥解密
* </p>
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.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(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
} /**
* 公钥加密 by zyl
* @param data
* @param publicKey
* @return
*/
public static byte[] encryptByPublicKey(byte[] data, Key publicKey) throws Exception{
// 对数据加密
/*根据公钥加密*/
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
int inputLen = data.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(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
} /**<p>
* 公钥加密
* </p>
* @param data 源数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.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(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
} /**
* 私钥加密by zyl
*/
public static byte[] encryptByPrivateKey(byte[] data, Key privateKey)throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
int inputLen = data.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(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
} /** *//**
* <p>
* 私钥加密
* </p>
* @param data 源数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = data.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(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
} /** *//**
* <p>
* 获取私钥
* </p>
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64Utils.encode(key.getEncoded());
} /** *//**
* <p>
* 获取公钥
* </p>
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64Utils.encode(key.getEncoded());
}
}
测试类:
testRSAUnitsV2
package com.rsa.test; import java.security.Key;
import java.util.Map; import org.junit.Test; import com.test.Rsa.RSAUtils_V2;
import com.test.util.MyUtils; public class testRSAUnitsV2 { static String publicKey2;
static String privateKey2; public static void main(String args[]){
try {
test3();
} catch (Exception e) {
e.printStackTrace();
} } /**
* 加密解密
* @throws Exception
*/
/**
* 生成密钥对,并保存为对应文本文件.
*/
public void test1() {
RSAUtils_V2 r2=new RSAUtils_V2();
try {
Map<String, Object> keyMap=RSAUtils_V2.genKeyPair();
RSAUtils_V2.createKeyFile(keyMap);
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 1读取test()方法中生成的密钥文件, 并在内存中生成密钥
* 2使用密钥加密解密文本.
*/
public static void test2() {
try {
Map<String, Object> keyMap2=RSAUtils_V2.getKeyByFile();
publicKey2 = RSAUtils_V2.getPublicKey(keyMap2);//获取公钥
privateKey2 = RSAUtils_V2.getPrivateKey(keyMap2);//获取私钥
System.err.println("公钥: \n\r" + publicKey2);
System.err.println("私钥: \n\r" + privateKey2); String str="这是一行没有任何意义的文字,你看完了等于没看,不是吗?";//.来加密我吧.I M KEY!
System.out.println(" 加密前="+str);
byte[] jiami=RSAUtils_V2.encryptByPublicKey(str.getBytes(), (Key)keyMap2.get("RSAPublicKey"));
System.out.println(" 加密后="+new String(jiami)); byte[] jiami2=RSAUtils_V2.decryptByPrivateKey(jiami, (Key)keyMap2.get("RSAPrivateKey"));
System.out.println(" 解密后="+new String(jiami2));
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* test2基础上:
* 加密后可以对byte进行hex.这样内容就不是乱码,大小更小,也便于进行传播.
* 解密前对hex进行转换hex2byte即可,然后解密即可
*/
public static void test3(){
try {
Map<String, Object> keyMap2 = RSAUtils_V2.getKeyByFile();
publicKey2 = RSAUtils_V2.getPublicKey(keyMap2);//获取公钥
privateKey2 = RSAUtils_V2.getPrivateKey(keyMap2);//获取私钥
System.err.println("公钥: \n\r" + publicKey2);
System.err.println("私钥: \n\r" + privateKey2);
String str = "这是一行没有任何意义的文字,你看完了等于没看,不是吗?据说长度太长会有问题.于是:" +
"日前拜仁董事会主席鲁梅尼格表示,鉴于目前球员们的比赛压力太大,国家队比赛场次应当减少。" +
"鲁梅尼格表示:“球员们的压力早已经超过了健康的范围之内,已经达到了身体所允许的上限。国家队" +
"比赛的增长是有责任的。”鲁梅尼格呼吁国际足联以及欧足联减少国家队比赛次数。“比赛应当以质量而不" +
"是数量为目标。”另外鲁梅尼格举出具体的数字表示,在过去的几十年里,球员们国家队的比赛数量增长了30%," +
"“贝肯鲍尔时代的球员们每年只需要参加8.5场国家队比赛,而穆勒们则需要参加大概13场。”而俱乐部则必须承担国" +
"家队比赛增多的风险。在周末的德甲联赛中拜仁客场0-0与汉堡互交白卷,赛前球队中场罗本已经进入首发阵容,但不慎" +
"在热身时受伤。据报道,罗本或将继续无缘拜仁下场对阵帕德博恩的比赛。在对阵汉堡的比赛前罗本已经被列入球队首发,但在热身时罗本再度受伤。“肌肉感觉有些紧。”随后原本计划被轮换的穆勒临时出场替代罗本。另外罗本表示这只是预防措施。但球队下一场对阵帕德博恩能够出场,罗本表示:“我也不能确定。”";//.来加密我吧.I M KEY!
System.out.println(" 加密前=" + str);
byte[] jiami = RSAUtils_V2.encryptByPublicKey(str.getBytes(),
(Key) keyMap2.get("RSAPublicKey"));
System.out.println(" 加密后=" + new String(jiami));
System.out.println(" 加密后长度=" + jiami.length);
//加密后hex
String afterhex=MyUtils.byteToHex(jiami);
System.out.println(" 加密并hex后=" + new String(afterhex));
System.out.println(" 加密并hex后长度=" + afterhex.length());
//反hex
byte[] afterReHEX=MyUtils.hexToByte(afterhex);
byte[] jiami2 = RSAUtils_V2.decryptByPrivateKey(afterReHEX,
(Key) keyMap2.get("RSAPrivateKey"));
System.out.println(" 解密后=" + new String(jiami2));
System.out.println(" 解密后长度=" + jiami2.length);
} catch (Exception e) {
}
}
}
执行test3 效果如下:
公钥: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCRM6FQTDPWppMTOJ3HFrpinxGUhQtQhaPXIGFBuwsqx3QsuJmVIX3DpJ0KU3cEUumDMM6qkTvFGtoIDeYQxuslUWCMFm+ma7DoDS+3RQ6nExQ5F3cTXhvXosrYYcADKP6pk8fVIiY+cq+yq/KV0OB6yOJ96N4wywhe6y3hldUXcwIDAQAB
私钥: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJEzoVBMM9amkxM4nccWumKfEZSFC1CFo9cgYUG7CyrHdCy4mZUhfcOknQpTdwRS6YMwzqqRO8Ua2ggN5hDG6yVRYIwWb6ZrsOgNL7dFDqcTFDkXdxNeG9eiythhwAMo/qmTx9UiJj5yr7Kr8pXQ4HrI4n3o3jDLCF7rLeGV1RdzAgMBAAECgYBV0DmqBx8r4M5TMcatftUwq+nr6KVDNXgbD9vqyOxUoAQc2gyKgnydP5BAJgvU1luDWTkKvUKhvrjUwcIScD1PrhyecjVMqb8tvmexefd1bcPq9OZpxQjR64pwRPjC7krOENR5moiIKhngSk4Qp/dk/xX6l+h+wLlBjneQsVDxYQJBAOFDuPitRRPds+vd33lYNr2IEiJkvIErxZUXRu4Pfc/e4m03dcyhJ3eqn7KoBL4trYQsboYl3HYpDkHfHxWMCf0CQQClA2M2KdBB1F7Kb0TymM5CtvNfBsSqADspkJeCmANwCNPKW4hzq++YyfFX5cqkSuuTlS+7vjvlCgYiXDjpVuovAkEAvIjU0HUcopLk2l1Zg5L8RccT/ms3hhjfhnfz6p1WnFscQXKwijK6+KH6hSmwxocuebhCTM51ZQPZpfIbbwpE9QJAdN/LW0eOW7HhWZwpx3H3VUVjZsDSdl4niS8CQNsOREHcUA04vkTfNOaDa/Az8N2nsSYPYvhAT98jrR6IqKyIvQJAda1Kya8NLWtSbmHBldqhjSxhkEZRofzHO38Qldvfs3XU4bsPZ1YkFruf8ilVdaFSVznX88YaFK9zEBBAix/KcA==
加密前=这是一行没有任何意义的文字,你看完了等于没看,不是吗?据说长度太长会有问题.于是:日前拜仁董事会主席鲁梅尼格表示,鉴于目前球员们的比赛压力太大,国家队比赛场次应当减少。鲁梅尼格表示:“球员们的压力早已经超过了健康的范围之内,已经达到了身体所允许的上限。国家队比赛的增长是有责任的。”鲁梅尼格呼吁国际足联以及欧足联减少国家队比赛次数。“比赛应当以质量而不是数量为目标。”另外鲁梅尼格举出具体的数字表示,在过去的几十年里,球员们国家队的比赛数量增长了30%,“贝肯鲍尔时代的球员们每年只需要参加8.5场国家队比赛,而穆勒们则需要参加大概13场。”而俱乐部则必须承担国家队比赛增多的风险。在周末的德甲联赛中拜仁客场0-0与汉堡互交白卷,赛前球队中场罗本已经进入首发阵容,但不慎在热身时受伤。据报道,罗本或将继续无缘拜仁下场对阵帕德博恩的比赛。在对阵汉堡的比赛前罗本已经被列入球队首发,但在热身时罗本再度受伤。“肌肉感觉有些紧。”随后原本计划被轮换的穆勒临时出场替代罗本。另外罗本表示这只是预防措施。但球队下一场对阵帕德博恩能够出场,罗本表示:“我也不能确定。”
加密后=e�z]����}�t�O�`����CD��/�I�tM/��9�`�z!����W_w<��W��ޣU�|�E�)�8�z�b��.:�Ha����֏���x<�k���,���(��l�Y%�`�aM�ji?��h�����pwuy��I$