一.XML格式秘钥转Pem格式
package VerifyLicense;
import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.*;
public class RSAXmlToPem {
private static final int PRIVATE_KEY = 1;
private static final int PUBLIC_KEY = 2;
private static final String[] PRIVATE_KEY_XML_NODES = { "Modulus", "Exponent", "P", "Q", "DP", "DQ", "InverseQ", "D" };
private static final String[] PUBLIC_KEY_XML_NODES = { "Modulus", "Exponent" };
/**
* xml格式秘钥转为Pem格式秘钥
* @param xmlStr xml格式私钥字符串
* @return pem格式秘钥
*/
public static String transXmlStrToPem (String xmlStr){
String pem = "";
try {
Document XMLSecKeyDoc = parseXMLStr(xmlStr);
int keyType = getKeyType(XMLSecKeyDoc);
if (keyType == PRIVATE_KEY) {
pem = convertXMLRSAPrivateKeyToPEM(XMLSecKeyDoc);
} else {
pem = convertXMLRSAPublicKeyToPEM(XMLSecKeyDoc);
}
}
catch (Exception e) {
e.printStackTrace();
}
System.out.println(pem);
return pem;
}
/**
* xml格式秘钥转为Pem格式秘钥
* @param path xml格式私钥文件地址
* @return pem格式秘钥
*/
public static String transXmlTotPem(String path){
String pem = "";
try {
Document XMLSecKeyDoc = parseXMLFile(path);
int keyType = getKeyType(XMLSecKeyDoc);
if (keyType == PRIVATE_KEY) {
pem = convertXMLRSAPrivateKeyToPEM(XMLSecKeyDoc);
} else {
pem = convertXMLRSAPublicKeyToPEM(XMLSecKeyDoc);
}
}
catch (Exception e) {
e.printStackTrace();
}
return pem;
}
/**
* 获得秘钥类型
* @param xmldoc
* @return
*/
private static int getKeyType(Document xmldoc) {
Node root = xmldoc.getFirstChild();
if (!root.getNodeName().equals("RSAKeyValue")) {
System.out.println("Expecting <RSAKeyValue> node, encountered <" + root.getNodeName() + ">");
return 0;
}
NodeList children = root.getChildNodes();
if (children.getLength() == PUBLIC_KEY_XML_NODES.length) {
return PUBLIC_KEY;
}
return PRIVATE_KEY;
}
/**
* 检查秘钥是否符合格式
* @param keyType
* @param xmldoc
* @return
*/
private static boolean checkXMLRSAKey(int keyType, Document xmldoc) {
Node root = xmldoc.getFirstChild();
NodeList children = root.getChildNodes();
String[] wantedNodes = {};
if (keyType == PRIVATE_KEY) {
wantedNodes = PRIVATE_KEY_XML_NODES;
} else {
wantedNodes = PUBLIC_KEY_XML_NODES;
}
for (int j = 0; j < wantedNodes.length; j++) {
String wantedNode = wantedNodes[j];
boolean found = false;
for (int i = 0; i < children.getLength(); i++) {
if (children.item(i).getNodeName().equals(wantedNode)) {
found = true;
break;
}
}
if (!found) {
System.out.println("Cannot find node <" + wantedNode + ">");
return false;
}
}
return true;
}
/**
* 将xml格式私钥转为PEM格式
* @param xmldoc
* @return
*/
private static String convertXMLRSAPrivateKeyToPEM(Document xmldoc) {
Node root = xmldoc.getFirstChild();
NodeList children = root.getChildNodes();
BigInteger modulus = null, exponent = null, primeP = null, primeQ = null,
primeExponentP = null, primeExponentQ = null,
crtCoefficient = null, privateExponent = null;
for (int i = 0; i < children.getLength(); i++) {
Node node = children.item(i);
String textValue = node.getTextContent();
if (node.getNodeName().equals("Modulus")) {
modulus = new BigInteger(b64decode(textValue));
} else if (node.getNodeName().equals("Exponent")) {
exponent = new BigInteger(b64decode(textValue));
} else if (node.getNodeName().equals("P")) {
primeP = new BigInteger(b64decode(textValue));
} else if (node.getNodeName().equals("Q")) {
primeQ = new BigInteger(b64decode(textValue));
} else if (node.getNodeName().equals("DP")) {
primeExponentP = new BigInteger(b64decode(textValue));
} else if (node.getNodeName().equals("DQ")) {
primeExponentQ = new BigInteger(b64decode(textValue));
} else if (node.getNodeName().equals("InverseQ")) {
crtCoefficient = new BigInteger(b64decode(textValue));
} else if (node.getNodeName().equals("D")) {
privateExponent = new BigInteger(b64decode(textValue));
}
}
try {
RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec (
modulus, exponent, privateExponent, primeP, primeQ,
primeExponentP, primeExponentQ, crtCoefficient);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey key = keyFactory.generatePrivate(keySpec);
return b64encode(key.getEncoded());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将xml格式公钥转为PEM格式
* @param xmldoc
* @return
*/
private static String convertXMLRSAPublicKeyToPEM(Document xmldoc) {
Node root = xmldoc.getFirstChild();
NodeList children = root.getChildNodes();
BigInteger modulus = null, exponent = null;
for (int i = 0; i < children.getLength(); i++) {
Node node = children.item(i);
String textValue = node.getTextContent();
if (node.getNodeName().equals("Modulus")) {
modulus = new BigInteger(b64decode(textValue));
} else if (node.getNodeName().equals("Exponent")) {
exponent = new BigInteger(b64decode(textValue));
}
}
try {
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(keySpec);
return b64encode(key.getEncoded());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将xml格式字符串格式化城Document格式
* @param xmlStr
* @return
*/
private static Document parseXMLStr(String xmlStr) {
try {
InputStream in=new ByteArrayInputStream(xmlStr.getBytes());
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(in);
return document;
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将某个包含xml的文件转换为Document格式
* @param filename
* @return
*/
private static Document parseXMLFile(String filename) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse( new File(filename) );
return document;
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
private static final String b64encode(byte[] data) {
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder() ;
String b64str = enc.encodeBuffer(data).trim();
return b64str;
}
private static final byte[] b64decode(String data) {
try {
sun.misc.BASE64Decoder dec = new sun.misc.BASE64Decoder() ;
byte[] bytes = dec.decodeBuffer(data.trim());
return bytes;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
二.RSA私钥解密,支持Pem格式秘钥,xml格式不支持
pom中加入依赖:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.12</version>
</dependency>
package VerifyLicense;
import java.io.*;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.*;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
public class RSAUtil {
/**
* RSA私钥解密
* @param strPath 加密字符串文件路径
* @param privateKeyPath xml私钥文件路径
* @return 铭文
*/
public static String decryptXmlRSA(String strPath, String privateKeyPath){
String str = readFile(strPath);
String privateKey = RSAXmlToPem.transXmlTotPem(privateKeyPath);
String code = "";
try {
code = decrypt(str,privateKey);
} catch (Exception e) {
e.printStackTrace();
}
return code;
}
/**
* RSA私钥解密
* @param str 加密字符串
* @param xmlPrivateKey xml格式私钥字符串
* @return 铭文
*/
public static String decryptXmlStrRSA(String str, String xmlPrivateKey){
String code = "";
String privateKey = RSAXmlToPem.transXmlStrToPem(xmlPrivateKey);
try {
code = decrypt(str,privateKey);
} catch (Exception e) {
e.printStackTrace();
}
return code;
}
/**
* RSA私钥解密,支持Pem格式秘钥,xml格式不支持
* @param str 加密字符串
* @param privateKey 私钥
* @return 铭文
* @throws Exception 解密过程中的异常信息
*/
public static String decrypt(String str, String privateKey) throws Exception{
//64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
/**
* 读取文件内容
* @param filepath
* @return
*/
public static String readFile(String filepath) {
FileReader re = null;
BufferedReader buff = null;
String line = "";
try {
File file = new File(filepath);
re = new FileReader(file);
buff = new BufferedReader(re);
String tempString = null;
while ((tempString = buff.readLine()) != null) {
line += tempString;
}
return line;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
re.close();
buff.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return line;
}
/**
* 寻找证书文件
* 证书文件一般会放在某个特定的文件夹,并以特定格式结尾,在不知道该验证证书文件完整名称的时候
* 我们寻找以某文件结尾的文件,前提是,该文件夹下只有一个该格式文件,否则应该以全名检索
* @param path
* @param endStr
* @return
*/
public static String getEncryptionFile(String path,String endStr) {
File file = new File(path);
File[] array = file.listFiles();
for (int i = 0; i < array.length; i++) {
if (array[i].isFile()) {
if (array[i].getPath().endsWith(endStr)){
return array[i].getPath();
}
} else if (array[i].isDirectory()) {
continue;
}
}
return "";
}
}