引文: http://blog.csdn.net/houzuoxin/article/details/38957969
package com.lvmama.clutter.utils;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import com.alibaba.dubbo.common.utils.StringUtils;
/**
*
* @author heyuxing
*
*/
public class RSAFileUtil {
public static final String CHARSET = "utf-8";
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGN_ALGORITHM = "SHA1withRSA";
public static String privateKeyPath = "C:\\Users\\Administrator\\Desktop\\HeartyPri.key";
public static PrivateKey privateK;
// private static String RSA_KEY_FILEPATH = ClutterConstant.getProperty("rsa.privatekey.filepath");
private static Logger logger = Logger.getLogger(RSAFileUtil.class);
public static void main(String[] args) throws Exception {
Map<String, String> dataStr = new HashMap<String, String>();
dataStr.put("orderId", "11111");
dataStr.put("objectType", "objectType");
dataStr.put("payAmountFen", "4154");
dataStr.put("paymentType", "paymentType");
dataStr.put("bizType", "bizType");
dataStr.put("royaltyParameters", "royaltyParameters");
dataStr.put("getPromotAmountFen", "1245");
System.out.println("map 集合: " + dataStr.toString());
String ss = signMapNotEncode(dataStr);
System.out.println("加签值: " + ss);
}
protected static String signMapNotEncode(Map<String, String> params) throws Exception {
String text = createLinkString(params, false);
return sign(text, CHARSET);
}
protected static String sign(String text, String charset) throws Exception {
PrivateKey privateK = getPrivateKey();
Signature signature = Signature.getInstance(SIGN_ALGORITHM);
signature.initSign(privateK);
signature.update(getContentBytes(text, charset));
byte[] result = signature.sign();
return Base64.encodeBase64String(result);
}
private static PrivateKey getPrivateKey() {
if(privateK == null) {
synchronized (RSAFileUtil.class) {
if(privateK == null) {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
if(StringUtils.isBlank(privateKeyPath)) {
// privateKeyPath = "/var/www/webapps/client-clutter/WEB-INF/classes/HeartyPri.key";
privateKeyPath = "C:\\Users\\Administrator\\Desktop\\HeartyPri.key";
}
fis = new FileInputStream(privateKeyPath);
ois = new ObjectInputStream(fis);
privateK = (PrivateKey) ois.readObject();
} catch (Exception e) {
logger.error("....RSAFileUtil.getPrivateKey is error....",e);
e.printStackTrace();
} finally {
if (ois != null ) {
try {
ois.close();
} catch (IOException e) {
logger.error("....RSAFileUtil.getPrivateKey is error....",e);
e.printStackTrace();
}
}
if (fis != null ) {
try {
fis.close();
} catch (IOException e) {
logger.error("....RSAFileUtil.getPrivateKey is error....",e);
e.printStackTrace();
}
}
}
}
}
}
return privateK;
}
private static byte[] getContentBytes(String content, String charset) {
if (charset == null || "".equals(charset)) {
return content.getBytes();
}
try {
return content.getBytes(charset);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:"
+ charset);
}
}
public static String createLinkString(Map<String, String> params,
boolean encode) {
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
String prestr = "";
Charset charset = Charset.forName("UTF-8");
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (StringUtils.isEmpty(value)) {
continue;
}
if (encode) {
try {
value = URLEncoder.encode(value, charset.name());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
prestr = prestr + key + "=" + value;
} else {
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}
}
通过生成工具,生成一对公钥,私钥;
RSAKeyGeneratorL:
package com.lvtu.utils;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
* 用于生产RSA公钥、私钥
* @author wxliyong
* @date 2016-10-14 15:32:41
*/
public class RSAKeyGenerator {
/** 这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低 */
private static final int KEY_SIZE = 512;
public static void main(String[] args) throws Exception {
KeyPair keyPair = generateKeyPair();
PublicKey pubKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
System.out.println("公钥:" + Base64.encodeBase64String(pubKey.getEncoded()));
System.out.println("私钥:" + Base64.encodeBase64String(privateKey.getEncoded()));
}
/**
* 生成密钥对
*
* @return KeyPair
* @throws Exception
*/
private static KeyPair generateKeyPair() throws Exception {
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider());
keyPairGen.initialize(KEY_SIZE, new SecureRandom());
KeyPair keyPair = keyPairGen.genKeyPair();
return keyPair;
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
}
utill:
package com.lvtu.utils;
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
/**
* RSA加密解密工具类<br>
* <font color="red">1、使用公钥加密,必须使用私钥解密;</font><br>
* <font color="red">2、使用私钥加密,则必须使用公钥解密</font><br>
* @author wxliyong
* @date 2016-10-14 15:33:25
*/
public class RSAUtils {
private static final String DEFAULT_CHARACTER = "UTF-8";
/** RSA最大加密明文大小 */
private static final int MAX_ENCRYPT_BLOCK = 117;
/** RSA最大解密密文大小 */
private static final int MAX_DECRYPT_BLOCK = 128;
public static void main(String[] args) throws Exception {
String pubKey = "MD0wDQYJKoZIhvcNAQEBBQADLAAwKQIiATEgdQwKkkIpjzdA3dqyWOHRj6YwLZICvX4FzCYFT8W4HQIDAQAB";
String primaryKey = "MIHGAgEAMA0GCSqGSIb3DQEBAQUABIGxMIGuAgEAAiIBMSB1DAqSQimPN0Dd2rJY4dGPpjAtkgK9fgXMJgVPxbgdAgMBAAECISaLmh2uTDGtfFkXia8x7oZ717KoPHSCWHcooEuAqOoeRQIRFsniPNjNomPbmtNHhNF36XsCEQ1jspMZf40QRdXyZw2bULVHAhEDQE48rBm6X1DHZ/k+I7xd3QIRA60DMW8mnUuCYKITuKCTH7ECEQf2xqNQbgwQvwba5k7iZFzm";
String content = "111111";
String encryptByPub = encryptByPub(pubKey, content);
System.out.println("公钥加密密文:" + encryptByPub);
String decryptByPrimary = decryptByPrimary(primaryKey, encryptByPub);
System.out.println("私钥解密明文:" + decryptByPrimary);
String encryptByPrimary = encryptByPrimary(primaryKey, content);
System.out.println("私钥加密密文:" + encryptByPrimary);
String decryptByPub = decryptByPub(pubKey, encryptByPrimary);
System.out.println("公钥解密明文:" + decryptByPub);
}
/**
* 使用公钥加密
* @param key 公钥
* @param content 明文
* @return String 密文
* @throws Exception
*/
public static String encryptByPub(String key, String content) throws Exception {
PublicKey pubKey = getPublicKey(key);
byte[] data = encrypt(pubKey, content.getBytes(DEFAULT_CHARACTER));
return Base64.encodeBase64String(data);
}
/**
* 使用私钥加密
* @param key 私钥
* @param content 明文
* @return String 密文
* @throws Exception
*/
public static String encryptByPrimary(String key, String content) throws Exception {
PrivateKey privateKey = getPrivateKey(key);
byte[] data = encrypt(privateKey, content.getBytes(DEFAULT_CHARACTER));
return Base64.encodeBase64String(data);
}
/**
* 使用公钥解密
* @param key 公钥
* @param content 密文
* @return String 明文
* @throws Exception
*/
public static String decryptByPub(String key, String content) throws Exception {
PublicKey pubKey = getPublicKey(key);
byte[] data = decrypt(pubKey, Base64.decodeBase64(content));
return new String(data, DEFAULT_CHARACTER);
}
/**
* 使用私钥解密
* @param key 私钥
* @param content 密文
* @return String 明文
* @throws Exception
*/
public static String decryptByPrimary(String key, String content) throws Exception {
PrivateKey privateKey = getPrivateKey(key);
byte[] data = decrypt(privateKey, Base64.decodeBase64(content));
return new String(data, DEFAULT_CHARACTER);
}
/**
* 得到公钥
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
private static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes = Base64.decodeBase64(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
/**
* 得到私钥
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
private static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = Base64.decodeBase64(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
/**
* 加密
* @param key 加密的密钥/公钥
* @param data 明文数据
* @return 密文数据
* @throws Exception
*/
private static byte[] encrypt(Key key, byte[] data) throws Exception {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] cache;
// 对数据分段加密
for (int offSet = 0; offSet<inputLen; offSet += MAX_ENCRYPT_BLOCK) {
if (inputLen - offSet > 117) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
}
byte[] encryptBytes = out.toByteArray();
out.close();
return encryptBytes;
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* 解密
* @param key 解密的密钥/公钥
* @param raw 密文数据
* @return 明文数据
* @throws Exception
*/
private static byte[] decrypt(Key key, byte[] raw) throws Exception {
ByteArrayOutputStream out = null;
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
int inputLen = raw.length;
out = new ByteArrayOutputStream();
byte[] cache;
// 对数据分段解密
for (int offSet = 0; offSet<inputLen; offSet += MAX_DECRYPT_BLOCK) {
byte[] subData = subArray(raw, offSet, MAX_DECRYPT_BLOCK);
cache = cipher.doFinal(subData);
out.write(cache, 0, cache.length);
}
byte[] decryptBytes = out.toByteArray();
return decryptBytes;
} catch (Exception e) {
throw new Exception(e.getMessage());
} finally {
if(out != null) {
out.close();
}
}
}
/**
*
* 截取byte数组中指定子集
*
* @autor: heyuxing 2014-12-18 下午12:25:31
* @param source 原byte数组
* @param offset 起始索引
* @param limit 截取的byte数组的最大长度
* @return
* @return byte[]
*/
private static byte[] subArray(byte[] source, int offset, int limit) {
int targetLen = 0;
if(source==null || offset>=source.length || offset<0 || limit<=0) {
return new byte[]{};
}else if(source.length-offset>limit) {
targetLen = limit;
}else {
targetLen = source.length-offset;
}
byte[] target = new byte[targetLen];
for(int i=0; i<targetLen; i++) {
target[i] = source[offset+i];
}
return target;
}
}
事例:
String primaryKey = Constant.getInstance().getValue("param.rsa.primary.key");
if(password.contains("%")) {
password = URLDecoder.decode(password, "UTF-8");
}
password = RSAUtils.decryptByPrimary(primaryKey, password);
request.setPassword(password);
package com.lvmama.pet.payfront.web;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.*;
/**
* Created by Administrator on 2016/10/28.
*/
public class Tesrt {
public static void main(String[] args) throws Exception {
Map<String, String> dataStr = new HashMap<String, String>();
dataStr.put("orderId", "11111");
dataStr.put("objectType", "objectType");
dataStr.put("payAmountFen", "4154");
dataStr.put("paymentType", "paymentType");
dataStr.put("bizType", "bizType");
dataStr.put("royaltyParameters", "royaltyParameters");
dataStr.put("getPromotAmountFen", "1245");
System.out.println("map 集合: " + dataStr.toString());
String sin = sign(createLinkString(dataStr, false), "C:\\Users\\Administrator\\Desktop\\rsa\\HeartyPri.key", "utf-8");
System.out.println("加签值: " + sin);
}
protected static String sign(String text, String privateKeyPath, String charset) throws Exception {
FileInputStream fis = new FileInputStream(privateKeyPath);
ObjectInputStream ois = new ObjectInputStream(fis);
PrivateKey privateK = (PrivateKey) ois.readObject();
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(privateK);
signature.update(getContentBytes(text, charset));
byte[] result = signature.sign();
return Base64.encodeBase64String(result);
}
private static byte[] getContentBytes(String content, String charset) {
if (charset == null || "".equals(charset)) {
return content.getBytes();
}
try {
return content.getBytes(charset);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
}
}
public static String createLinkString(Map<String, String> params, boolean encode) {
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
String prestr = "";
Charset charset = Charset.forName("UTF-8");
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (StringUtils.isEmpty(value)){
continue;
}
if (encode) {
try {
value = URLEncoder.encode(value, charset.name());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
prestr = prestr + key + "=" + value;
} else {
prestr = prestr + key + "=" + value + "&";
}
}
return prestr;
}
}