我已经成功使用代码生成了CSR(证书签名请求)并填入了相关信息。现在,我需要指导来了解如何使用Java和/或BouncyCastle读取CSR内容。
非常感谢任何指导或想法。
我已经成功使用代码生成了CSR(证书签名请求)并填入了相关信息。现在,我需要指导来了解如何使用Java和/或BouncyCastle读取CSR内容。
非常感谢任何指导或想法。
解决方法:
以下是代码:
public class EncryptDecrypt {
private Logger LOG = LoggerFactory.getLogger(EncryptDecrypt.class);
private final String COUNTRY = "2.5.4.6";
private final String STATE = "2.5.4.8";
private final String LOCALE = "2.5.4.7";
private final String ORGANIZATION = "2.5.4.10";
private final String ORGANIZATION_UNIT = "2.5.4.11";
private final String COMMON_NAME = "2.5.4.3";
@Test
public void testReadCertificateSigningRequest() {
String csrPEM = "-----BEGIN CERTIFICATE REQUEST-----\n" +
"MIICwjCCAaoCAQAwfTELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0Zsb3JpZGExEzAR\n" +
"BgNVBAcTCkJvY2EgUmF0b24xGzAZBgNVBAoTEkxvb25leSBUb29ucywgSW5jLjEU\n" +
"MBIGA1UECxMLRGV2ZWxvcG1lbnQxFDASBgNVBAMTC2V4YW1wbGUuY29tMIIBIjAN\n" +
"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiJCj31d1Rp+aKz/GTkedaiS/VSCc\n" +
"PRARYgXukobjgBHx46HjldAcfg/DoANn5lEQaFxaIZJLbZ/AdLUyw/hUbU0CjWXv\n" +
"pN3Ep3o9XgRTPkIFoI22VOI/O2ZLjBq/E4DWyVmv+vG6BK0LRh7hykzPCw6KIRR9\n" +
"NCmUMJMQX5d5P/r1lR5H399pnLcLsrHoWDwBSEDgkGWyxnvEB0+/bIz42T3qnlFt\n" +
"7avarxlHG2p5DoRTf8GJ+6imY88ZeBW/Nk18aDINsAHWLv383JICIAsZ3VuMk8m/\n" +
"Z/Z5b21zIuZECDJjZjvAAjr/shVLB+Pck5+HJy6tqj79MJOQu+jKIrK8VwIDAQAB\n" +
"oAAwDQYJKoZIhvcNAQEFBQADggEBAGtuAAHG4OC9jSRjGWSqfMXTDMz9tgekDREA\n" +
"SYv5QIrOXsMzwbgDw8LxRJZEskl4JJOnjwEvUXWUF1M6XmG2h358nOnrkOlsumHw\n" +
"Tx5gGSr6S6aJO/HG46erctE8aWpnFZYMfuEkul4ApsIufL7Bxqs3NHZWcrWBlLIP\n" +
"aVCKx1FPRMC36Tj3EslbuUB/iTRt90Nfq1IxHMIKiwCiSNJSqfRVLANhI8MUbOjB\n" +
"CBly1wcH68WWNkyvHVvbcF/B9AfYG9AqWjZjygKpyf81VZWctXhDc8UtomqrblXN\n" +
"mvz4RKpIhZQLuuxlBrdzJkPm2sOdtdZghebCRRVWdjsig4sylgQ=\n" +
"-----END CERTIFICATE REQUEST-----";
PKCS10CertificationRequest csr = convertPemToPKCS10CertificationRequest(csrPEM);
X500Name x500Name = csr.getSubject();
System.out.println("x500Name is: " + x500Name + "\n");
// country is 2.5.4.6
System.out.println("COUNTRY: " + getX500Field(COUNTRY, x500Name));
// state is 2.5.4.8
System.out.println("STATE: " + getX500Field(STATE, x500Name));
// locale is 2.5.4.7
System.out.println("LOCALE: " + getX500Field(LOCALE, x500Name));
}
private String getX500Field(String asn1ObjectIdentifier, X500Name x500Name) {
RDN[] rdnArray = x500Name.getRDNs(new ASN1ObjectIdentifier(asn1ObjectIdentifier));
String retVal = null;
for (RDN item : rdnArray) {
retVal = item.getFirst().getValue().toString();
}
return retVal;
}
private PKCS10CertificationRequest convertPemToPKCS10CertificationRequest(String pem) {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
PKCS10CertificationRequest csr = null;
ByteArrayInputStream pemStream = null;
try {
pemStream = new ByteArrayInputStream(pem.getBytes("UTF-8"));
} catch (UnsupportedEncodingException ex) {
LOG.error("UnsupportedEncodingException, convertPemToPublicKey", ex);
}
Reader pemReader = new BufferedReader(new InputStreamReader(pemStream));
PEMParser pemParser = new PEMParser(pemReader);
try {
Object parsedObj = pemParser.readObject();
System.out.println("PemParser returned: " + parsedObj);
if (parsedObj instanceof PKCS10CertificationRequest) {
csr = (PKCS10CertificationRequest) parsedObj;
}
} catch (IOException ex) {
LOG.error("IOException, convertPemToPublicKey", ex);
}
return csr;
}
private String toPEM(Object key) {
StringWriter sw = new StringWriter();
PEMWriter pem = new PEMWriter(sw);
try {
pem.writeObject(key);
pem.close();
} catch (IOException e) {
System.out.printf("IOException: %s%n", e);
}
return sw.toString();
}
}
ASN1ObjectIdentifier
存储在 BCStyle
静态类中作为 public static final ASN1ObjectIdentifier
,因此诸如 COUNTRY
的东西不需要从零开始重新创建。但它不是枚举。 - EpicPandaForce<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk15on</artifactId>
<version>1.62</version>
</dependency>
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import java.io.*;
public class CSRObject {
private final X500Name x500Name;
public CSRObject(final String csr) throws IOException {
final Reader pemReader = new StringReader(csr);
final PEMParser pemParser = new PEMParser(pemReader);
x500Name = ((PKCS10CertificationRequest) pemParser.readObject()).getSubject();
}
public String get(final CSRObjectEnum field) {
RDN[] rdnArray = x500Name.getRDNs(new ASN1ObjectIdentifier(field.code));
String retVal = null;
for (RDN item : rdnArray) {
retVal = item.getFirst().getValue().toString();
}
return retVal;
}
public enum CSRObjectEnum {
COUNTRY("2.5.4.6"),
STATE("2.5.4.8"),
LOCALE("2.5.4.7"),
ORGANIZATION("2.5.4.10"),
ORGANIZATION_UNIT("2.5.4.11"),
COMMON_NAME("2.5.4.3"),//
;
private final String code;
CSRObjectEnum(final String sCode) {
code = sCode;
}
}
}
你可以使用以下方法进行测试:
@Test
public void test() throws IOException {
final CSRObject csr = new CSRObject(TEST_CERTIF);
for (final CSRObject.CSRObjectEnum field : CSRObject.CSRObjectEnum.values()){
LOGGER.info("{}:{}", field.name(), csr.get(field));
}
}
with TEST_CERTIF is String
private static final String TEST_CERTIF = "-----BEGIN CERTIFICATE REQUEST-----\n" +
"...\n" +
"-----END CERTIFICATE REQUEST-----\n";
我在David的答案基础上构建了一个单元测试,以验证在Android上使用Kotlin编写的CSR内容。它假定您最初拥有字符串格式的CSR。CSR是使用SpongyCastle JcaPKCS10CertificationRequestBuilder
生成的。
class yourCsrTestClass {
...
private lateinit var csrContent: PKCS10CertificationRequest
...
@Test
fun yourCsrTest() {
//This creates a CSR with SpongyCastle which we will test
val csr = yourCSRService.generateRequest()
//Convert our CSR string in modified code from David
convertCsrString(csr)
//Get x500Name subject
val x500Name = csrContent.subject
//Assert test as true if content matches as intended
//This can be applied to any CSR attribute
assertTrue(getX500Field(BCStrictStyle.O.toString(), x500Name) == "Your intender organization name")
}
...
private fun convertCsrString(pemCsr: String) {
val stream = ByteArrayInputStream(pemCsr.toByteArray())
val pemReader = BufferedReader(InputStreamReader(stream))
var pemParser: PEMParser? = null
try {
pemParser = PEMParser(pemReader)
val parsedObj = pemParser.readObject()
println("PemParser returned: $parsedObj")
if (parsedObj is PKCS10CertificationRequest) {
csrContent = parsedObj
}
} catch (ex: IOException) {
Log.d("IOException, convertPemToPublicKey", ex.toString())
} finally {
if (pemParser != null) {
IOUtils.closeQuietly(pemParser)
}
}
}
...
private fun getX500Field(asn1ObjectIdentifier: String, x500Name: X500Name): String {
val rdnArray = x500Name.getRDNs(ASN1ObjectIdentifier(asn1ObjectIdentifier))
return rdnArray[0].first.value.toString()
}
}