|
package com.ruoyi.admin.utils.util;
|
|
import java.io.*;
|
import java.security.*;
|
import java.security.cert.Certificate;
|
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateFactory;
|
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
import java.util.Enumeration;
|
|
/** */
|
/**
|
* <p>
|
* RSA公钥/私钥/签名工具包
|
* </p>
|
* <p>
|
* 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)
|
* </p>
|
* <p>
|
* 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
|
* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
|
* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
|
* </p>
|
*
|
* @author IceWee
|
* @date 2012-4-26
|
* @version 1.0
|
*/
|
public class RSAUtils {
|
|
/** */
|
/**
|
* 加密算法RSA
|
*/
|
public static final String KEY_ALGORITHM = "RSA";
|
|
/** */
|
/**
|
* 签名算法
|
*/
|
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
|
|
/**
|
* 获取RSA私钥串
|
*
|
* @param in
|
* RSA私钥证书文件流
|
* @param fileSuffix
|
* RSA私钥名称,决定编码类型|PFX、JKS、PEM...
|
* @param password
|
* RSA私钥保护密钥|口令
|
* @param keyAlgorithm
|
* 密钥算法
|
* @return RSA私钥对象
|
* @throws ServiceException
|
*/
|
public static String getRSAPrivateKeyByFileSuffix(InputStream in, String fileSuffix, String password, String keyAlgorithm)
|
throws Exception {
|
String keyType = "";
|
if ("keystore".equalsIgnoreCase(fileSuffix)) {
|
keyType = "JKS";
|
} else if ("pfx".equalsIgnoreCase(fileSuffix) || "p12".equalsIgnoreCase(fileSuffix)) {
|
keyType = "PKCS12";
|
} else if ("jck".equalsIgnoreCase(fileSuffix)) {
|
keyType = "JCEKS";
|
} else if ("pem".equalsIgnoreCase(fileSuffix) || "pkcs8".equalsIgnoreCase(fileSuffix)) {
|
keyType = "PKCS8";
|
} /*else if ("pkcs1".equalsIgnoreCase(fileSuffix)) {
|
keyType = "PKCS1";
|
} */else {
|
keyType = "JKS";
|
}
|
|
try {
|
PrivateKey priKey = null;
|
if ("JKS".equals(keyType) || "PKCS12".equals(keyType) || "JCEKS".equals(keyType)) {
|
KeyStore ks = KeyStore.getInstance(keyType);
|
if (password != null) {
|
char[] cPasswd = password.toCharArray();
|
ks.load(in, cPasswd);
|
Enumeration<String> aliasenum = ks.aliases();
|
String keyAlias = null;
|
while (aliasenum.hasMoreElements()) {
|
keyAlias = (String) aliasenum.nextElement();
|
priKey = (PrivateKey) ks.getKey(keyAlias, cPasswd);
|
if (priKey != null)
|
break;
|
}
|
}
|
} else {
|
BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
StringBuilder sb = new StringBuilder();
|
String readLine = null;
|
while ((readLine = br.readLine()) != null) {
|
if (readLine.charAt(0) == '-') {
|
continue;
|
} else {
|
sb.append(readLine);
|
sb.append('\r');
|
}
|
}
|
|
if ("PKCS8".equals(keyType)) {
|
System.out.println("1");
|
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(sb.toString()));
|
System.out.println("2");
|
KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
|
System.out.println("3");
|
priKey = keyFactory.generatePrivate(priPKCS8);
|
System.out.println("4");
|
|
|
} /*else if ("PKCS1".equals(keyType)) {
|
RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(sb.toString().getBytes()));
|
KeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());
|
KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
|
priKey = keyFactory.generatePrivate(rsaPrivKeySpec);
|
}*/
|
}
|
|
if (priKey != null) {
|
return Base64.encode(priKey.getEncoded());
|
}
|
else {
|
return null;
|
}
|
} catch (FileNotFoundException e) {
|
throw new FileNotFoundException("私钥路径文件不存在");
|
} catch (KeyStoreException e) {
|
throw new KeyStoreException("获取KeyStore对象异常");
|
} catch (IOException e) {
|
throw new IOException("读取私钥异常");
|
} catch (NoSuchAlgorithmException e) {
|
throw new NoSuchAlgorithmException("生成私钥对象异常");
|
} catch (CertificateException e) {
|
throw new CertificateException("加载私钥密码异常");
|
} catch (UnrecoverableKeyException e) {
|
throw new UnrecoverableKeyException("生成私钥对象异常");
|
} catch (InvalidKeySpecException e) {
|
throw new InvalidKeySpecException("生成私钥对象异常");
|
} finally {
|
try {
|
if (in != null) {
|
in.close();
|
}
|
} catch (IOException e) {
|
}
|
}
|
}
|
|
/** */
|
/**
|
* <p>
|
* 用私钥对信息生成数字签名
|
* </p>
|
*
|
* @param data 已加密数据
|
* @param privateKey 私钥(BASE64编码)
|
* @return
|
* @throws Exception
|
*/
|
public static String sign(byte[] data, String privateKey) throws Exception {
|
byte[] keyBytes = Base64.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 Base64.encode(signature.sign());
|
}
|
|
/** */
|
/**
|
* <p>
|
* 校验数字签名
|
* </p>
|
*
|
* @param data 已加密数据
|
* @param publicKey 公钥(BASE64编码)
|
* @param sign 数字签名
|
* @param keyType 编码格式
|
* @return
|
* @throws Exception
|
*/
|
public static boolean verify(byte[] data, String publicKey, String sign, String keyType)
|
throws Exception {
|
if ("PKCS12".equals(keyType)) {
|
return verify(data, publicKey, sign);
|
} else if ("X.509".equals(keyType)) {
|
byte[] keyBytes = Base64.decode(publicKey);
|
CertificateFactory factory = CertificateFactory.getInstance(keyType);
|
Certificate cert = factory.generateCertificate(new ByteArrayInputStream(keyBytes));
|
PublicKey pubKey = cert.getPublicKey();
|
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
signature.initVerify(pubKey);
|
signature.update(data);
|
return signature.verify(Base64.decode(sign));
|
}
|
throw new Exception("==>校验数字签名:未知的证书公钥编码格式!");
|
}
|
|
/** */
|
/**
|
* <p>
|
* 校验数字签名
|
* </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 = Base64.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(Base64.decode(sign));
|
}
|
}
|