這裏使用的Java原生的security和bouncycastle 這幾個包
1.Maven座標
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcmail-jdk16 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk16</artifactId>
<version>1.46</version>
</dependency>
> 注意這裏千萬要注意版本問題 這兩個jar版本一定要統一 否則會出現很多莫名其妙的錯誤
2.直接上工具類 CSRUtils.class
package com.xinchacha.security.utils;
import java.io.*;
import java.security.*;
import org.apache.tomcat.util.codec.binary.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import sun.security.pkcs10.PKCS10;
import sun.security.rsa.RSAPrivateCrtKeyImpl;
import sun.security.x509.X500Name;
/**
* @ClassName CSRUtils
* @Description TODO
* @Author XuWenXiao
* @Date 2020/5/13 10:00
* @Version 1.0
**/
public class CSRUtils {
public KeyPair kp = null;
private static final String SHA_256WITHRSA="SHA256withRSA";
private static final String ENCRYPTION_RSA="RSA";
private static final Integer KEY_SIZE2048=2048;
private static final Integer KEY_SIZE4096=4096;
private static final String DV_SSL = "^([A-Z]|[a-z]|[0-9]|[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~!@#¥%……&*()――+|{}【】‘;:”“'。,、?]){6,20}$";
/**
* TODO 根據相關信息生成證書籤發請求
*
* @param alg 加密算法 <p>這裏使用SHA256withRSA(SHA256)</p>
* @param size 密鑰長度
* @param commonName_oid 域名CN 驗證非法域名
* @param orgUnitName_oid 部門/單位
* @param orgName_oid 公司/組織
* @param localityName_oid 國家/地區
* @param stateName_oid 省份
* @param countryName_oid 城市
* @return String <p>返回證書籤名請求字符串</p>
* @Author xuwenxiao
*/
public String generateCSR(String alg,int size,String commonName_oid,String orgUnitName_oid,String orgName_oid,String localityName_oid,String stateName_oid,String countryName_oid) {
Security.addProvider(new BouncyCastleProvider());
String strCSR = "";
String sigAlg;
try {
if (alg == null || alg.length() <= 0) {
sigAlg = SHA_256WITHRSA;
} else {
sigAlg = alg;
int algSize = KEY_SIZE2048;
if (size != 0) {
algSize = size;
}
/** 加密算法 **/
KeyPairGenerator kpg = KeyPairGenerator.getInstance(ENCRYPTION_RSA);
/** 指定密鑰長度 **/
kpg.initialize(algSize, new SecureRandom());
kp = kpg.generateKeyPair();
PublicKey publicKey = kp.getPublic();
String s = encodePublicKey(publicKey);
System.out.println("公鑰"+s);
PrivateKey privateKey = kp.getPrivate();
RSAPrivateCrtKeyImpl rsaPrivateCrtKey= (RSAPrivateCrtKeyImpl) privateKey;
System.out.println(rsaPrivateCrtKey.toString());
//這裏要注意 因爲祕鑰還在研究中 所以需要進行再次開發
/**getPrivateExponent**/
System.out.println(rsaPrivateCrtKey.getPrivateExponent().toString());
/**getCrtCoefficient**/
System.out.println(rsaPrivateCrtKey.getCrtCoefficient().toString());
/**getModulus**/
System.out.println(rsaPrivateCrtKey.getModulus().toString());
/**getPrimeExponentP**/
System.out.println(rsaPrivateCrtKey.getPrimeExponentP().toString());
/**getPrimeExponentQ**/
System.out.println(rsaPrivateCrtKey.getPrimeExponentQ().toString());
/**getPrimeP**/
System.out.println(rsaPrivateCrtKey.getPrimeP().toString());
/**getPrimeQ**/
System.out.println(rsaPrivateCrtKey.getPrimeQ().toString());
/**getPublicExponent**/
System.out.println(rsaPrivateCrtKey.getPublicExponent().toString());
// System.out.println(rsaPrivateCrtKey.getCrtCoefficient()+
// rsaPrivateCrtKey.getModulus()+
// rsaPrivateCrtKey.getPrimeExponentP()+
// rsaPrivateCrtKey.getPrimeExponentQ()+
// rsaPrivateCrtKey.getPrimeP()+
// rsaPrivateCrtKey.getPrimeQ()+
// rsaPrivateCrtKey.getPrivateExponent()+
// rsaPrivateCrtKey.getPublicExponent());
// String s1 = encoded.toString();
// System.out.println("私鑰"+s1);
PKCS10 pkcs10 = new PKCS10(publicKey);
Signature signature = Signature.getInstance(sigAlg);
signature.initSign(privateKey);
/**設置域名**/
if (!commonName_oid.matches(DV_SSL)){
throw new RuntimeException("請檢查您輸入的域名是否合法覈對後重新輸入");
}
String commonName = whetherNull(commonName_oid);
/**設置組織機構**/
String orgUnitName = whetherNull(orgUnitName_oid);
/**設置部門單位**/
String orgName=whetherNull(orgName_oid);
/**設置國家地區**/
String localityName=whetherNull(localityName_oid);
/**設置省份信息**/
String stateName=whetherNull(stateName_oid);
/**設置城市信息**/
String countryName=whetherNull(countryName_oid);
X500Name x500Name = new X500Name(commonName,orgUnitName,orgName,localityName,stateName,countryName);
pkcs10.encodeAndSign(x500Name, signature);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
pkcs10.print(ps);
String strPEMCSR = baos.toString();
/** 對生成CSR密鑰進行替換 將begin 和 end 的內容去除**/
strCSR = strPEMCSR.replaceAll("\r|\n", "");
//strCSR = strCSR.replaceAll("-----BEGIN NEW CERTIFICATE REQUEST-----", "");
//strCSR = strCSR.replaceAll("-----END NEW CERTIFICATE REQUEST-----", "");
return strCSR;
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
return strCSR;
}
public static String encodePublicKey(PublicKey publicKey) {
return StringUtils.newStringUtf8(Base64.encode(publicKey.getEncoded()));
}
/**
* 驗證非空
* @param ar
*/
public String whetherNull(String ar){
String whether="";
if (!org.apache.commons.lang3.StringUtils.isBlank(ar)){
whether=ar;
}else{
whether="";
}
return whether;
}
3.Main函數調用 查看結果 請求參數在工具類中已經標明 可以參考
CSRUtils csrUtils= new CSRUtils();
String s = csrUtils.generateCSR("SHA256withRSA", 2048, "www.zhangsan.com", "百度", "張三", "中國", "北京", "昌平");
System.out.println(s);