Generating CSR using Java

  sonic0002        2016-05-25 04:49:17       26,741        0          English  简体中文  繁体中文  ภาษาไทย  Tiếng Việt 

一個 CSR(憑證簽署請求)是一種由應用程式產生的請求,並將其發送給憑證授權單位以建立可分發的已簽署憑證。它通常包含憑證資訊,例如主體名稱、公開金鑰資訊和簽名資訊。

在 Java 中,可以使用 keytool 透過選項 -certreq 產生憑證請求。 但有時如果應用程式想要以程式設計方式建立 CSR,keytool 無法提供協助,而應改用 Java 提供的 API 來產生 CSR。

基本上,產生 CSR 的步驟如下:

  1. 取得 CSR 所請求的密鑰對。它可以使用 KeyPairGenerator 產生,也可以從金鑰儲存庫載入(建議)
  2. 建立憑證請求的主體,並為憑證請求建立簽名
  3. 使用步驟 1 中密鑰對的私鑰簽署憑證請求
  4. 取得編碼的憑證請求數據,並將其儲存並發送給 CA 以建立憑證。

為示範目的,我們將使用 KeyPairGenerator 取得密鑰對,但在實際應用中,最好將密鑰對儲存在金鑰儲存庫中。

以下是使用 RSA 建立憑證請求的範例。

public class CSRGenerator {
	public static void main(String[] args) {
		CSRGenerator csrGeneration = new CSRGenerator();
		
		// 產生密鑰對
		KeyPair keyPair = csrGeneration.generateKeyPair("RSA", 1024);
		System.out.println("KeyPair generated");
		
		byte[] csrData = csrGeneration.generateCSR("SHA256WithRSA", keyPair);
		
		System.out.println(new String(csrData));
	}
	
	/**
	 * 產生要簽署的 CSR
	 * 
	 * @param sigAlg
	 * @param keyPair
	 * @return
	 */
	byte[] generateCSR(String sigAlg, KeyPair keyPair) {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		PrintStream printStream = new PrintStream(outStream);
		
		try {
			X500Name x500Name = new X500Name("CN=EXAMPLE.COM");
			
			Signature sig = Signature.getInstance(sigAlg);
			
			sig.initSign(keyPair.getPrivate());

			PKCS10 pkcs10 = new PKCS10(keyPair.getPublic());
//			pkcs10.encodeAndSign(new X500Signer(sig, x500Name));   // 適用於 Java 6
			pkcs10.encodeAndSign(x500Name, sig);                   // 適用於 Java 7 和 Java 8
			pkcs10.print(printStream);
	        
			byte[] csrBytes = outStream.toByteArray();
			
			return csrBytes;
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			if(null != outStream) {
				try {
					outStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if(null != printStream) {
				printStream.close();
			}
		}
		
		return new byte[0];
	}

	/**
	 * 產生所需的密鑰對
	 * 
	 * @param alg
	 * @param keySize
	 * @return
	 */
	KeyPair generateKeyPair(String alg, int keySize) {
		try{
			KeyPairGenerator keyPairGenerator = null;
			keyPairGenerator = KeyPairGenerator.getInstance(alg);
			
			keyPairGenerator.initialize(keySize);
			
			return keyPairGenerator.generateKeyPair();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		
		return null;
	}
}

請注意,在呼叫 PKCS10.encodeAndSign() 時,Java 6 和 Java 7 之間存在一些差異。Java 7 不再具有 X500Signer

如果您使用的是 IBM Java 而不是 Oracle Java,則產生憑證請求的方式有所不同。請見下文。

public class CSRGenerator {
	public static void main(String[] args) {
		CSRGenerator csrGeneration = new CSRGenerator();
		
		// 產生密鑰對
		KeyPair keyPair = csrGeneration.generateKeyPair("RSA", 1024);
		System.out.println("KeyPair generated");
		
		byte[] csrData = csrGeneration.generateCSR("SHA256WithRSA", keyPair);
		
		System.out.println(new String(csrData));
	}
	
	/**
	 * 產生要簽署的 CSR
	 * 
	 * @param sigAlg
	 * @param keyPair
	 * @return
	 */
	byte[] generateCSR(String sigAlg, KeyPair keyPair) {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		PrintStream printStream = new PrintStream(outStream);
		
		try {
			X500Name x500Name = new X500Name("CN=EXAMPLE.COM");
			
	        CertificateExtensions ext = new CertificateExtensions();
	        PKCSAttributes attrs = new PKCSAttributes().addAttribute(new PKCSAttribute(PKCSOID.EXTENSION_REQUEST_OID, ext));
	        
	        CertificationRequestInfo certInfo = new CertificationRequestInfo(x500Name, keyPair.getPublic(), attrs);
	        CertificationRequest request = new CertificationRequest(certInfo);
	        request = request.sign(sigAlg, keyPair.getPrivate());
	        request.print(printStream);
	        
			byte[] csrBytes = outStream.toByteArray();
			
			return csrBytes;
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			if(null != outStream) {
				try {
					outStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if(null != printStream) {
				printStream.close();
			}
		}
		
		return new byte[0];
	}

	/**
	 * 產生所需的密鑰對
	 * 
	 * @param alg
	 * @param keySize
	 * @return
	 */
	KeyPair generateKeyPair(String alg, int keySize) {
		try{
			KeyPairGenerator keyPairGenerator = null;
			keyPairGenerator = KeyPairGenerator.getInstance(alg);
			
			keyPairGenerator.initialize(keySize);
			
			return keyPairGenerator.generateKeyPair();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		
		return null;
	}
}

以 BASE64 編碼產生的憑證請求應如下所示:

-----BEGIN NEW CERTIFICATE REQUEST-----
MIIBZjCB0AIBADAWMRQwEgYDVQQDEwtFWEFNUExFLkNPTTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEAgXneACRkW0QvpuuNhzo8OOmxe7xPzd3UZJ9MOEA5VhP5QvWGMGFNITGmubL1I2AWmsHz
yMxwO0SHPFNclo4oSm+Cu2d67d28vingYBGEBrVXIwg3j1CVADcGjb39TcYL77fofBem8XNDCw0N
WKLaTqpnVaAtqvnE0+r7O3BZZg8CAwEAAaARMA8GCSqGSIb3DQEJDjECMAAwDQYJKoZIhvcNAQEL
BQADgYEAb5jNx6ASGpgTXTNz5UrD6BrTyLZYyTmlQwI0EjhG0lVY5sYiQGz7t6JQP62aqRFfM7vo
dYMnKxeuApp5LSY3EdyY1F5I20PPTbpSSP529pV5gIQZk4FZMoth7dvWgBH3pqB0BkHQ1g+wdWof
m2imkOR1D+7Yn6xvQ/Be9mXienU=
-----END NEW CERTIFICATE REQUEST-----

如果您在 Java 中產生憑證請求時遇到困難,希望這能對您有所幫助。

CSR  CERTIFICATE REQUEST  SECURITY  JAVA 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

GitHub PR to remove password