diff --git a/README.md b/README.md
index 3263f57..bcd6d19 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ JAVA 1.8버전 사용자들을 위한 세션키 발급 및 개인정보 암복
예시)
```
-0.0.12
+0.0.13
```
pom.xml 을 사용하시면 아래와 같이 추가해주세요.
diff --git a/build.gradle b/build.gradle
index 3a58ad5..c710d48 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ plugins {
}
group 'com.github.toss'
-version '0.0.12'
+version '0.0.13'
sourceCompatibility = JavaVersion.VERSION_1_6
targetCompatibility = JavaVersion.VERSION_1_6
@@ -25,6 +25,7 @@ repositories {
dependencies {
implementation 'commons-codec:commons-codec:1.15'
+ implementation 'org.bouncycastle:bcpkix-jdk18on:1.77'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
testImplementation 'javax.json:javax.json-api:1.1.4'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
diff --git a/src/main/java/im/toss/cert/sdk/PKCS7CertificateExtractor.java b/src/main/java/im/toss/cert/sdk/PKCS7CertificateExtractor.java
new file mode 100644
index 0000000..9daddb4
--- /dev/null
+++ b/src/main/java/im/toss/cert/sdk/PKCS7CertificateExtractor.java
@@ -0,0 +1,38 @@
+package im.toss.cert.sdk;
+
+import org.bouncycastle.cert.jcajce.JcaCertStoreBuilder;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.CMSSignedData;
+
+import java.security.GeneralSecurityException;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.util.Collection;
+
+public class PKCS7CertificateExtractor {
+ public static String extractCertificate(String pkcs7Data) {
+ try {
+ CMSSignedData signedData = new CMSSignedData(Base64Utils.decode(pkcs7Data));
+ CertStore certStore = new JcaCertStoreBuilder().addCertificates(signedData.getCertificates()).build();
+ Collection extends Certificate> certificates = certStore.getCertificates(null);
+ return convertToPem(certificates.iterator().next());
+ } catch (CMSException e) {
+ throw new RuntimeException(e.getCause());
+ } catch (CertificateEncodingException e) {
+ throw new RuntimeException(e.getCause());
+ } catch (CertStoreException e) {
+ throw new RuntimeException(e.getCause());
+ } catch (GeneralSecurityException e) {
+ throw new RuntimeException(e.getCause());
+ }
+ }
+
+ private static String convertToPem(Certificate certificate) throws CertificateEncodingException {
+ String pemCertPre = "-----BEGIN CERTIFICATE-----\n";
+ String pemCertPost = "\n-----END CERTIFICATE-----";
+ String pemCert = Base64Utils.encodeToString(certificate.getEncoded());
+ return pemCertPre + pemCert + pemCertPost;
+ }
+}
diff --git a/src/main/java/im/toss/cert/sdk/TossCertSessionGenerator.java b/src/main/java/im/toss/cert/sdk/TossCertSessionGenerator.java
index e02c56b..bdfb6d3 100644
--- a/src/main/java/im/toss/cert/sdk/TossCertSessionGenerator.java
+++ b/src/main/java/im/toss/cert/sdk/TossCertSessionGenerator.java
@@ -9,7 +9,7 @@
import java.util.UUID;
public class TossCertSessionGenerator {
- private final static String version = "v1_0.0.12";
+ private final static String version = "v1_0.0.13";
private final static String publicKey = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoVdxG0Qi9pip46Jw9ImSlPVD8+L2mM47ey6EZna7D7utgNdh8Tzkjrm1Yl4h6kPJrhdWvMIJGS51+6dh041IXcJEoUquNblUEqAUXBYwQM8PdfnS12SjlvZrP4q6whBE7IV1SEIBJP0gSK5/8Iu+uld2ctJiU4p8uswL2bCPGWdvVPltxAg6hfAG/ImRUKPRewQsFhkFvqIDCpO6aeaR10q6wwENZltlJeeRnl02VWSneRmPqqypqCxz0Y+yWCYtsA+ngfZmwRMaFkXcWjaWnvSqqV33OAsrQkvuBHWoEEkvQ0P08+h9Fy2+FhY9TeuukQ2CVFz5YyOhp25QtWyQI+IaDKk+hLxJ1APR0c3tmV0ANEIjO6HhJIdu2KQKtgFppvqSrZp2OKtI8EZgVbWuho50xvlaPGzWoMi9HSCb+8ARamlOpesxHH3O0cTRUnft2Zk1FHQb2Pidb2z5onMEnzP2xpTqAIVQyb6nMac9tof5NFxwR/c4pmci+1n8GFJIFN18j2XGad1mNyio/R8LabqnzNwJC6VPnZJz5/pDUIk9yKNOY0KJe64SRiL0a4SNMohtyj6QlA/3SGxaEXb8UHpophv4G9wN1CgfyUamsRqp8zo5qDxBvlaIlfkqJvYPkltj7/23FHDjPi8q8UkSiAeu7IV5FTfB5KsiN8+sGSMCAwEAAQ==";
private final RSACipher rsaCipher;
diff --git a/src/test/java/im/toss/cert/sdk/ExampleTest.java b/src/test/java/im/toss/cert/sdk/ExampleTest.java
index 265ff39..a03adb4 100644
--- a/src/test/java/im/toss/cert/sdk/ExampleTest.java
+++ b/src/test/java/im/toss/cert/sdk/ExampleTest.java
@@ -6,6 +6,7 @@
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
@@ -13,13 +14,15 @@
import java.net.URL;
import java.util.Scanner;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
@Disabled // 실행전에 해당라인을 삭제해주세요.
class ExampleTest {
// 0. 세션 생성기를 사전에 1회만 생성해 주세요.
TossCertSessionGenerator tossCertSessionGenerator = new TossCertSessionGenerator();
+ final String accessToken = "eyJraWQiOiJjZXJ0IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJ0ZXN0X2E4ZTIzMzM2ZDY3M2NhNzA5MjJiNDg1ZmU4MDZlYjJkIiwiYXVkIjoidGVzdF9hOGUyMzMzNmQ2NzNjYTcwOTIyYjQ4NWZlODA2ZWIyZCIsIm5iZiI6MTcwOTAyMDA5OSwic2NvcGUiOlsiY2EiXSwiaXNzIjoiaHR0cHM6Ly9jZXJ0LnRvc3MuaW0iLCJleHAiOjE3NDA1NTYwOTksImlhdCI6MTcwOTAyMDA5OSwianRpIjoiZDc3NmUxZmEtZmNkMy00MDE4LTg2MGMtZDA0NTY0YmUxY2U5In0.hQDc7eeY6-a-0tLfcsAO_Tejbmu_Sd7f80P90NtTy6T4HjEUQNji13sMdkhPeibnonE0E8d4fdsyFy2J2KQFLIqFNjV-jPypjm9XcF2yUBwBfG7Jq7k1BBuigPXTN1NistNpnE24F0nNlMzsGZi72YePIFEayFi_SQN5GUwZ9MZbQenGA9sKct0heqKxQj7wuyELgvT7dCFtZ5EU_C_DDhvgtyauGvD4ubtxj2_-SskAnr54LZhW-cDF-rdsAD9knbhcnscpZKXnGVNlXbQzgrVfWNEYlJeZ9bwagdgYh67VrC8SNBoGPuXsKU4eUV17lh_TwB9M2lPkBJLwgaJVgA";
+
@Test
void request() throws Exception {
// 1. 개인정보가 포함되어 있는 인증요청 API 호출 전에 세션을 생성해 주세요.
@@ -34,52 +37,33 @@ void request() throws Exception {
String encryptedUserBirthday = tossCertSession.encrypt(userBirthday);
// 3. 인증요청 API 를 호출해주세요.
- URL url = new URL("https://cert.toss.im/api/v2/sign/user/auth/request");
- HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
- httpConn.setRequestMethod("POST");
-
- httpConn.setRequestProperty("Authorization", "Bearer eyJraWQiOiJjZXJ0IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJ0ZXN0X2E4ZTIzMzM2ZDY3M2NhNzA5MjJiNDg1ZmU4MDZlYjJkIiwiYXVkIjoidGVzdF9hOGUyMzMzNmQ2NzNjYTcwOTIyYjQ4NWZlODA2ZWIyZCIsIm5iZiI6MTY0OTIyMjk3OCwic2NvcGUiOlsiY2EiXSwiaXNzIjoiaHR0cHM6XC9cL2NlcnQudG9zcy5pbSIsImV4cCI6MTY4MDc1ODk3OCwiaWF0IjoxNjQ5MjIyOTc4LCJqdGkiOiI4MDNjNDBjOC1iMzUxLTRmOGItYTIxNC1iNjc5MmNjMzBhYTcifQ.cjDZ0lAXbuf-KAgi3FlG1YGxvgvT3xrOYKDTstfbUz6CoNQgvd9TqI6RmsGZuona9jIP6H12Z1Xb07RIfAVoTK-J9iC5_Yp8ZDdcalsMNj51pPP8wso86rn-mKsrx1J5Rdi3GU58iKt0zGr4KzqSxUJkul9G4rY03KInwvl692HU19kYA9y8uTI4bBX--UPfQ02G0QH9HGTPHs7lZsISDtyD8sB2ikz5p7roua7U467xWy4BnRleCEWO2uUaNNGnwd7SvbjhmsRZqohs9KzDUsFjVhSiRNdHL53XJQ5zFHwDF92inRZFLu6Dw8xttPtNHwAD1kT84uXJcVMfEHtwkQ");
- httpConn.setRequestProperty("Content-Type", "application/json");
- httpConn.setDoOutput(true);
- OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
-/* json
-{
- "requestType": "USER_PERSONAL",
- "triggerType": "PUSH",
- "sessionKey": tossCertSession.getSessionKey(),
- "userName": encryptedUserName,
- "userPhone": encryptedUserPhone,
- "userBirthday": encryptedUserBirthday
-}
-*/
+ /* json
+ {
+ "requestType": "USER_PERSONAL",
+ "triggerType": "PUSH",
+ "sessionKey": tossCertSession.getSessionKey(),
+ "userName": encryptedUserName,
+ "userPhone": encryptedUserPhone,
+ "userBirthday": encryptedUserBirthday
+ }
+ */
String requestBody = Json.createObjectBuilder()
- .add("requestType", "USER_PERSONAL")
- .add("triggerType", "PUSH")
- // 3.1 세션키를 넣어주세요.
- .add("sessionKey", tossCertSession.getSessionKey())
- // 3.2 tossCertSession 로 암호화된 개인정보를 넣어주세요.
- .add("userName", encryptedUserName)
- .add("userPhone", encryptedUserPhone)
- .add("userBirthday", encryptedUserBirthday)
- .build()
- .toString();
- writer.write(requestBody);
- writer.flush();
- writer.close();
-
- httpConn.getOutputStream().close();
- InputStream responseStream = httpConn.getResponseCode() == 200
- ? httpConn.getInputStream()
- : httpConn.getErrorStream();
- Scanner s = new Scanner(responseStream).useDelimiter("\\A");
- String response = s.hasNext() ? s.next() : "";
+ .add("requestType", "USER_PERSONAL")
+ .add("triggerType", "PUSH")
+ // 3.1 세션키를 넣어주세요.
+ .add("sessionKey", tossCertSession.getSessionKey())
+ // 3.2 tossCertSession 로 암호화된 개인정보를 넣어주세요.
+ .add("userName", encryptedUserName)
+ .add("userPhone", encryptedUserPhone)
+ .add("userBirthday", encryptedUserBirthday)
+ .build()
+ .toString();
+
+ JsonObject responseObject = postUrl("https://cert.toss.im/api/v2/sign/user/auth/request", requestBody);
- JsonReader responseReader = Json.createReader(new StringReader(response));
- JsonObject responseObject = responseReader.readObject();
System.out.println("\n--------------------------- 인증 요청 결과 -------------------------------------");
System.out.println("인증 txId: " + responseObject.getJsonObject("success").getString("txId"));
System.out.println("----------------------------------------------------------------------------\n");
- assertEquals(1, 1);
}
// 결과호출을 하기전에 토스앱에서 인증을 완료해 주세요.
@@ -87,52 +71,79 @@ void request() throws Exception {
@Test
void result() throws Exception {
// 0. 인증 요청 결과에서 응답받은 인증 txId 로 변경한 후 테스트 해주세요.
- String txId = "2122cb6d-46f9-4e72-86eb-3f71c3c97507";
+ String txId = "인증 txId";
// 1. 인증 결과 조회 API 호출 전에 세션을 생성해 주세요.
TossCertSession tossCertSession = tossCertSessionGenerator.generate();
// 2. 인증요청 API 를 호출해주세요.
- URL url = new URL("https://cert.toss.im/api/v2/sign/user/auth/result");
+ /* json
+ {
+ "sessionKey": tossCertSession.getSessionKey(),
+ "txId": txId
+ }
+ */
+ String requestBody = Json.createObjectBuilder()
+ // 2.1 세션키를 넣어주세요.
+ .add("sessionKey", tossCertSession.getSessionKey())
+ // 2.2 인증 요청 결과의 txId 를 넣어주세요.
+ .add("txId", txId)
+ .build()
+ .toString();
+
+ JsonObject responseObject = postUrl("https://cert.toss.im/api/v2/sign/user/auth/result", requestBody);
+
+ // 3. 결과를 복호화 합니다.
+ String encryptedCi = responseObject.getJsonObject("success").getJsonObject("personalData").getString("ci");
+ String ci = tossCertSession.decrypt(encryptedCi);
+ System.out.println("\n--------------------------- 인증 결과 조회 CI ----------------------------------");
+ System.out.println("복호화 된 CI: " + ci);
+ System.out.println("----------------------------------------------------------------------------\n");
+
+ // 4. 인증서 유효성을 검사합니다.
+ String signature = responseObject.getJsonObject("success").getString("signature");
+ String pemCertificate = PKCS7CertificateExtractor.extractCertificate(signature);
+
+ /* json
+ {
+ "certificate": pemCertificate
+ }
+ */
+ requestBody = Json.createObjectBuilder()
+ // 2.1 세션키를 넣어주세요.
+ .add("certificate", pemCertificate)
+ // 2.2 인증 요청 결과의 txId 를 넣어주세요.
+ .build()
+ .toString();
+
+ responseObject = postUrl("https://cert.toss.im/api/v1/certificate/validate", requestBody);
+
+ assertTrue(responseObject.getJsonObject("success").getBoolean("valid"));
+ assertTrue(responseObject.getJsonObject("success").getBoolean("enabled"));
+ }
+
+ private JsonObject postUrl(String urlString, String requestBody) throws IOException {
+ URL url = new URL(urlString);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("POST");
- httpConn.setRequestProperty("Authorization", "Bearer eyJraWQiOiJjZXJ0IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJ0ZXN0X2E4ZTIzMzM2ZDY3M2NhNzA5MjJiNDg1ZmU4MDZlYjJkIiwiYXVkIjoidGVzdF9hOGUyMzMzNmQ2NzNjYTcwOTIyYjQ4NWZlODA2ZWIyZCIsIm5iZiI6MTY0OTIyMjk3OCwic2NvcGUiOlsiY2EiXSwiaXNzIjoiaHR0cHM6XC9cL2NlcnQudG9zcy5pbSIsImV4cCI6MTY4MDc1ODk3OCwiaWF0IjoxNjQ5MjIyOTc4LCJqdGkiOiI4MDNjNDBjOC1iMzUxLTRmOGItYTIxNC1iNjc5MmNjMzBhYTcifQ.cjDZ0lAXbuf-KAgi3FlG1YGxvgvT3xrOYKDTstfbUz6CoNQgvd9TqI6RmsGZuona9jIP6H12Z1Xb07RIfAVoTK-J9iC5_Yp8ZDdcalsMNj51pPP8wso86rn-mKsrx1J5Rdi3GU58iKt0zGr4KzqSxUJkul9G4rY03KInwvl692HU19kYA9y8uTI4bBX--UPfQ02G0QH9HGTPHs7lZsISDtyD8sB2ikz5p7roua7U467xWy4BnRleCEWO2uUaNNGnwd7SvbjhmsRZqohs9KzDUsFjVhSiRNdHL53XJQ5zFHwDF92inRZFLu6Dw8xttPtNHwAD1kT84uXJcVMfEHtwkQ");
+ httpConn.setRequestProperty("Authorization", "Bearer " + accessToken);
httpConn.setRequestProperty("Content-Type", "application/json");
httpConn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
-/* json
-{
- "sessionKey": tossCertSession.getSessionKey(),
- "txId": txId
-}
-*/
- String requestBody = Json.createObjectBuilder()
- // 2.1 세션키를 넣어주세요.
- .add("sessionKey", tossCertSession.getSessionKey())
- // 2.2 인증 요청 결과의 txId 를 넣어주세요.
- .add("txId", txId)
- .build()
- .toString();
+
writer.write(requestBody);
writer.flush();
writer.close();
httpConn.getOutputStream().close();
InputStream responseStream = httpConn.getResponseCode() == 200
- ? httpConn.getInputStream()
- : httpConn.getErrorStream();
+ ? httpConn.getInputStream()
+ : httpConn.getErrorStream();
Scanner s = new Scanner(responseStream).useDelimiter("\\A");
String response = s.hasNext() ? s.next() : "";
- JsonReader responseReader = Json.createReader(new StringReader(response));
- JsonObject responseObject = responseReader.readObject();
- // 3. 결과를 복호화 합니다.
- String encryptedCi = responseObject.getJsonObject("success").getJsonObject("personalData").getString("ci");
- String ci = tossCertSession.decrypt(encryptedCi);
- System.out.println("\n--------------------------- 인증 결과 조회 CI ----------------------------------");
- System.out.println("복호화 된 CI: " + ci);
- System.out.println("----------------------------------------------------------------------------\n");
- assertEquals(1, 1);
+ JsonReader responseReader = Json.createReader(new StringReader(response));
+ return responseReader.readObject();
}
}
diff --git a/src/test/java/im/toss/cert/sdk/PKCS7CertificateExtractorTest.java b/src/test/java/im/toss/cert/sdk/PKCS7CertificateExtractorTest.java
new file mode 100644
index 0000000..3b4034d
--- /dev/null
+++ b/src/test/java/im/toss/cert/sdk/PKCS7CertificateExtractorTest.java
@@ -0,0 +1,86 @@
+package im.toss.cert.sdk;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class PKCS7CertificateExtractorTest {
+
+ @Test
+ void test() {
+ String pemCertificate = PKCS7CertificateExtractor.extractCertificate(pkcs7Data);
+ assertEquals(expectedPemCertificate, pemCertificate);
+ }
+
+ private final String pkcs7Data =
+ "MIIIZAYJKoZIhvcNAQcCoIIIVTCCCFECAQExDzANBglghkgBZQMEAgEFADAeBgkqhkiG9w0BBwGg" +
+ "EQQPZG9jdW1lbnQgc2FtcGxloIIGJjCCBiIwggQKoAMCAQICBAFAvqIwDQYJKoZIhvcNAQELBQAw" +
+ "UTELMAkGA1UEBgwCS1IxGzAZBgNVBAoMElZpdmEgUmVwdWJsaWNhIEluYzESMBAGA1UECwwJVG9z" +
+ "cyBDZXJ0MREwDwYDVQQDDAhUb3NzIENBMTAeFw0yNDAyMTUwNTIzNDdaFw0yNzAyMTQxNDU5NTla" +
+ "MHwxCzAJBgNVBAYTAktSMRswGQYDVQQKDBJWaXZhIFJlcHVibGljYSBJbmMxEjAQBgNVBAsMCVRv" +
+ "c3MgQ2VydDEoMCYGCgmSJomT8ixkAQEMGDcwMDI3MjEyMDIxMTExODgwMjAwMDAwMTESMBAGA1UE" +
+ "AwwJ7KCV7J246raMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkx0j1LpuVyn0G8RH" +
+ "oXleMrB27nf4uH57lr1Bchgkp5CysakjIQ/Q06Gosr4JmlrfPYiAlPHYcqTwKvU/uxUK7GoH9Ymx" +
+ "K8Z4xFJuHAQdMzMS63QVq5LH5VFjujutpR0vY5rQOSaQZUTSuybSlI9GxCUJwh0bSZhPUmHrpURl" +
+ "Qj//fGk8+LpBDsXUECypGq7UlM5M4z1bOOYA1I3SyCmvnqIiMd4xNx+Vy1bRvB3U6fE/vsplYFvz" +
+ "Efrcc2xVfnPGypskQZ0iv0ydw6TegAMkOGUttZQik7wMyZ7in4lbpidpTdyzGpoQtbUm3A56tbWG" +
+ "N4y9ru0RvtbvJVsTftULVQIDAQABo4IB1TCCAdEwfgYDVR0jBHcwdYAUIOEEYoA6EFhC3FSBskx+" +
+ "jPX3qh+hWqRYMFYxCzAJBgNVBAYMAktSMRswGQYDVQQKDBJWaXZhIFJlcHVibGljYSBJbmMxEjAQ" +
+ "BgNVBAsMCVRvc3MgQ2VydDEWMBQGA1UEAwwNVG9zcyBSb290IENBMYIBAjAdBgNVHQ4EFgQUGGl2" +
+ "Nn0TMLprdD5gjlLyzrJPOgUwDgYDVR0PAQH/BAQDAgbAMIGLBgNVHSABAf8EgYAwfjB8BgsqgxqM" +
+ "myIFAQEBAzBtMCsGCCsGAQUFBwIBFh9odHRwOi8vY2EuY2VydC50b3NzLmltL2Nwcy5odG1sMD4G" +
+ "CCsGAQUFBwICMDIeMABUAGgAaQBzACAAaQBzACAAVABvAHMAcwAgAGMAZQByAHQAaQBmAGkAYwBh" +
+ "AHQAZTBbBgNVHR8EVDBSMFCgTqBMhkpodHRwOi8vY2EuY2VydC50b3NzLmltL2NybC90b3NzX2Ny" +
+ "bF9kcDJwNzAwNy5jcmw/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDA1BggrBgEFBQcBAQQpMCcw" +
+ "JQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLmNlcnQudG9zcy5pbS8wDQYJKoZIhvcNAQELBQADggIB" +
+ "AC2CSrLGoNRT9KtjA5iGGSD8oOuc7gKcxn19B9gE2fcfe8tl3CiUYCBs6GTO8U29q0CeDVadmN0m" +
+ "dOE1V7qMDCdjEQLf4cskMKn0LNj406b+LhsYJPks+9Ra4RAl+P5QMrkVnfKS9HmM+k1snvMJXMV+" +
+ "zHwapai0C2cK1dKAttL+WZH5VhP2P48yDCRmoaB8ZzQ1YhS+PVyqtvGqSJBYbJusBXulMULcxbFq" +
+ "d/bSbIuyKEvUsd+6NbhT5jKs8EFbZ/fUPRMZusJj/VepIhwyb4hK3QiTgAq88Z8Tcofzq/1oV4Mm" +
+ "dRcj7IGdcSd2k6JgP+R6UObNaSTjjDLC9JfiOtXbnz9Lh55fG48r11qP2oZukyJGFdjI6HSiYScA" +
+ "cloc2INMFzifWioY3rG/bucLBqJGs5CU3ZYNaTKsGMnU7GPGCm3Rvh14QYB3I918VT8nrlcdiWZl" +
+ "MiPj6QUNSdTDuTgUDr/ud50VaD0ZhRNWouZ9w7V+Be+gGpv08HR6Ebdy+MuecxjjpIwPsbeBwjfg" +
+ "KPB+aEMdgYfVb8t/TQimbH8vxEUlct8+NRVawLe5F4ZXRMtr8WfbhTPU3aJiraemy7OGXxDkdRkO" +
+ "DHhG82Gjl8AQ4Rs5wveJvnT3a0/UUwBb3XTvYylGCHbw8i+ShbZ0ZU9E6anycByWlBZ16Agq4seR" +
+ "MYIB7zCCAesCAQEwWTBRMQswCQYDVQQGDAJLUjEbMBkGA1UECgwSVml2YSBSZXB1YmxpY2EgSW5j" +
+ "MRIwEAYDVQQLDAlUb3NzIENlcnQxETAPBgNVBAMMCFRvc3MgQ0ExAgQBQL6iMA0GCWCGSAFlAwQC" +
+ "AQUAoGkwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjQwMjI2MTIy" +
+ "MTQzWjAvBgkqhkiG9w0BCQQxIgQgtFv6KxZyYKTYL0BTDjk64Y7QBNMHVQwwXxAOO9HsDV4wDQYJ" +
+ "KoZIhvcNAQEBBQAEggEAhnqCF4z8tKfszHoBL57oiN4+Odn1rN8ZOUdVnrlFbKG9NbQgysAx9otF" +
+ "tF5PGtICTOaRZmPe6VQjxE7QbJv2GGuQX3ezVolM0I3RsCrDkIVycgopCvjZlITq36gnZSCiyAsz" +
+ "lVET5mLOQQpsvUWCPaTUjeYghRqE8ItwNtuQoKwy78RLLdQQvF7Q+mJf3H9GSKPzOGl51Hrnc5jx" +
+ "ZVJ+1fNGqjOdgggyHiUvFtap8Jja6tEQtt6LGkPdCnNprJjTHOWu7yzn5jmACWUvyY+BgbCF0vJL" +
+ "jiJTlKe5W1NK8G3jBJe9pLDQlyFbsScBYr1AqQx+ChusfcQ+c9COGGFbKg==";
+
+ private final String expectedPemCertificate =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "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" +
+ "\n-----END CERTIFICATE-----";
+}