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.SecureRandom;
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 java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* RSA非对称加密,对于长度超出117的字符串做了分段加密处理
* @author Administrator
*
*/
public class RSAUtil {
private final static Logger logger = LoggerFactory.getLogger(RSAUtil.class);
/**
* 随机生成密钥对
* @throws NoSuchAlgorithmException
*/
public static Map<String, Object> genKeyPair() {
try {
final Map<String, Object> keyMap = new HashMap<>();
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(1024,new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
// 得到私钥字符串
String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
// 将公钥和私钥保存到Map
keyMap.put("publicKey",publicKeyString); //0表示公钥
keyMap.put("privateKey",privateKeyString); //1表示私钥
logger.info("-----publicKey = " + publicKeyString);
logger.info("-----privateKey = " + privateKeyString);
return keyMap;
} catch (NoSuchAlgorithmException e) {
logger.error("生成RSA密钥对异常", e);
}
return null;
}
/**
* 加密
* @param message 需要加密的字符串
* @param publicKey 公钥
* @return
*/
public static String encrypt(final String message, final String publicKey ) {
//base64编码的公钥
try {
final byte[] decoded = Base64.decodeBase64(publicKey);
final RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
final Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
final byte[] bytes = message.getBytes("UTF-8");
final int len = bytes.length;//字符串长度
int offset = 0;//偏移量
int i = 0;//所分的段数
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
while (len > offset) {
byte[] cache;
if (len - offset > 117) {
cache = cipher.doFinal(bytes, offset, 117);
} else {
cache = cipher.doFinal(bytes, offset, len - offset);
}
bos.write(cache);
i++;
offset = 117 * i;
}
bos.close();
final String encryptMessage = Base64.encodeBase64String(bos.toByteArray());
return encryptMessage;
} catch (InvalidKeyException | InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException
| IllegalBlockSizeException | BadPaddingException | IOException e) {
logger.error("使用公钥对数据加密异常", e);
}
return null;
}
/**
* 解密
* @param message 需要解密的密文
* @param privateKey 私钥
* @return
*/
public static String decrypt(String message, final String privateKey) {
try {
logger.info("message1 = " + message);
if (message.contains(" ")) {
logger.info("解码前的字符串包含空格");
message = message.replaceAll(" ", "+");
}
logger.info("message2 = " + message);
//base64编码的私钥
final byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
//64位解码加密后的字符串
final byte[] inputByte = Base64.decodeBase64(message.getBytes("UTF-8"));
final int len = inputByte.length;//密文
int offset = 0;//偏移量
int i = 0;//段数
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
while (len - offset > 0) {
byte[] cache;
if (len - offset > 128) {
cache = cipher.doFinal(inputByte, offset, 128);
} else {
cache = cipher.doFinal(inputByte, offset, len - offset);
}
bos.write(cache);
i++;
offset = 128 * i;
}
bos.close();
return new String(bos.toByteArray(), "UTF-8");
} catch (InvalidKeyException | InvalidKeySpecException | NoSuchAlgorithmException
| NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | IOException e) {
logger.error("使用私钥对数据解密异常", e);
}
return null;
}
public static void main(String[] args) {
genKeyPair();
String encryptMsg = "T0KMag6KpIBvTMZkP3q/ewfPQrXEDRaBH2IJI1lDgEZjgbhy1QHM94cHXkS4oGqNwVUkgBeomt8DISZyqFVxlLkVla/pxer7Z+yoVehhRAmFH++0ZJf72FNwqIi9DIT4++ngEqFmzbH6c4Pf0D+8tvZ24ZQrzAqXak8sRORNEeU=YWRDfYOi0/sAVa8z6s4U97GaIMPPorvovMn6Pv9aDDy2MGjoGjJP7woRlnHbTE2UF1HyWW7rKzdI2rraqrctiBnjC5Zc6eFo/R2GQc/za/5Dnsyfj3+GspYEAp5+ChYhQp6AzM0NEFCtbgpL4OVE4GDqk/dHCY4HYtxxq+1wrKU=";
String pub = "";
String pri = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAILBzEP7Wbt1PBiNR9GBvMPv3n63/FzFOj+hk0WUu+H7aQqaSex1edKXHlnG5OCJYVEagUredK3oMqoKFdAMdlqL3XXsp5hGPFptfAithFowT1WGMc1IWbJeE3E2wP9wWuTWVHLIhGBs/lJDcxLrlXAqKrMyNsDSj0Uzh8dxGgrpAgMBAAECgYAEnF7emtNsN9MZrom0ypVkd2XqJATDJLVMHx95WahSbLIkjJJEw1O7aFbKpafWfyGuYXfjsvp8U27N7jMctgPKWniqYaOLvOt7Jk0qFYPD2UxjRsyI87R20yj2VAxBHuQqBU/0neMNSkb37fnw/dsvOvGWlTNSaz0DZgl6CHQMnQJBANy5iBQVwXeTsLRobdsrkZaL5DLwpD0QC1xAosl2xDEA41q86uLsRhQZM8EuGAof3UpJwNAhUn36eUuvjByr6/sCQQCXp29OxjGXP08Fzv4ceMHWG/+mWzhN7Yo/U7Gf2XG7f5Fv2jmYwNks44ugvyr6skTDprtaAfoQ2aCyr8qRretrAkAl+hYbvpKHDHY+1CjyqNBn4rHkwdrAVt5dhRF9MF4ZQFnd5ttTJ+v20U9CUbf5JfphKcdvCAy1eD8ecpnc5Qe5AkAXY0gEMwaU17udHrYLuAfUuE6t3iWJxxdp+sNK7qLekqbgRBxb1WnoxVLUQIclUHbQYZdFI0bocFebFwc7fkHvAkAKbXqMNGhojmfMY4NNUEWhcNlDfTdua9VbrHEjFlxHG2Y0R518pzofgBj0CGWGlHbY6lpaX/IbHzlMFrT92xdi";
System.err.println(decrypt(encryptMsg, pri));
}
}