From 0a16ec17e9d703a1f9dde88fe80d161d019a20cf Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 4 Oct 2023 15:11:47 +0200 Subject: [PATCH] Add property to enable key verification on PEM SSL bundles Closes gh-37727 --- .../ssl/PemSslBundleProperties.java | 14 +++ .../ssl/PropertiesSslBundle.java | 3 +- .../boot/ssl/pem/KeyVerifier.java | 104 ++++++++++++++++++ .../boot/ssl/pem/PemSslStoreBundle.java | 96 ++++++++++++---- .../boot/ssl/pem/KeyVerifierTests.java | 90 +++++++++++++++ .../boot/ssl/pem/PemSslStoreBundleTests.java | 30 +++++ .../org/springframework/boot/ssl/pem/ca.crt | 19 ++++ .../org/springframework/boot/ssl/pem/ca.pem | 27 +++++ .../org/springframework/boot/ssl/pem/key1.crt | 19 ++++ .../org/springframework/boot/ssl/pem/key1.pem | 28 +++++ .../boot/ssl/pem/key2-chain.crt | 38 +++++++ .../org/springframework/boot/ssl/pem/key2.crt | 19 ++++ .../org/springframework/boot/ssl/pem/key2.pem | 28 +++++ 13 files changed, 494 insertions(+), 21 deletions(-) create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/KeyVerifier.java create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/KeyVerifierTests.java create mode 100644 spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/ca.crt create mode 100644 spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/ca.pem create mode 100644 spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key1.crt create mode 100644 spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key1.pem create mode 100644 spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2-chain.crt create mode 100644 spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2.crt create mode 100644 spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2.pem diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PemSslBundleProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PemSslBundleProperties.java index 16798cb2cb..d98939350f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PemSslBundleProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PemSslBundleProperties.java @@ -23,6 +23,7 @@ import org.springframework.boot.ssl.pem.PemSslStoreBundle; * * @author Scott Frederick * @author Phillip Webb + * @author Moritz Halbritter * @since 3.1.0 * @see PemSslStoreBundle */ @@ -38,6 +39,11 @@ public class PemSslBundleProperties extends SslBundleProperties { */ private final Store truststore = new Store(); + /** + * Whether to verify that the private key matches the public key. + */ + private boolean verifyKeys; + public Store getKeystore() { return this.keystore; } @@ -46,6 +52,14 @@ public class PemSslBundleProperties extends SslBundleProperties { return this.truststore; } + public boolean isVerifyKeys() { + return this.verifyKeys; + } + + public void setVerifyKeys(boolean verifyKeys) { + this.verifyKeys = verifyKeys; + } + /** * Store properties. */ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundle.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundle.java index b25b88ad14..a1c8e9522f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundle.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PropertiesSslBundle.java @@ -109,7 +109,8 @@ public final class PropertiesSslBundle implements SslBundle { private static SslStoreBundle asSslStoreBundle(PemSslBundleProperties properties) { PemSslStoreDetails keyStoreDetails = asStoreDetails(properties.getKeystore()); PemSslStoreDetails trustStoreDetails = asStoreDetails(properties.getTruststore()); - return new PemSslStoreBundle(keyStoreDetails, trustStoreDetails, properties.getKey().getAlias()); + return new PemSslStoreBundle(keyStoreDetails, trustStoreDetails, properties.getKey().getAlias(), null, + properties.isVerifyKeys()); } private static PemSslStoreDetails asStoreDetails(PemSslBundleProperties.Store properties) { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/KeyVerifier.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/KeyVerifier.java new file mode 100644 index 0000000000..6b79c0a305 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/KeyVerifier.java @@ -0,0 +1,104 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.ssl.pem; + +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; + +/** + * Performs checks on keys, e.g., if a public key and a private key belong together. + * + * @author Moritz Halbritter + */ +class KeyVerifier { + + private static final byte[] DATA = "Just some piece of data which gets signed".getBytes(StandardCharsets.UTF_8); + + /** + * Checks if the given private key belongs to the given public key. + * @param privateKey the private key + * @param publicKey the public key + * @return whether the keys belong together + */ + Result matches(PrivateKey privateKey, PublicKey publicKey) { + try { + if (!privateKey.getAlgorithm().equals(publicKey.getAlgorithm())) { + // Keys are of different type + return Result.NO; + } + String algorithm = getSignatureAlgorithm(privateKey.getAlgorithm()); + if (algorithm == null) { + return Result.UNKNOWN; + } + byte[] signature = createSignature(privateKey, algorithm); + return verifySignature(publicKey, algorithm, signature); + } + catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException ex) { + return Result.UNKNOWN; + } + } + + private static byte[] createSignature(PrivateKey privateKey, String algorithm) + throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { + Signature signer = Signature.getInstance(algorithm); + signer.initSign(privateKey); + signer.update(DATA); + return signer.sign(); + } + + private static Result verifySignature(PublicKey publicKey, String algorithm, byte[] signature) + throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { + Signature verifier = Signature.getInstance(algorithm); + verifier.initVerify(publicKey); + verifier.update(DATA); + try { + if (verifier.verify(signature)) { + return Result.YES; + } + else { + return Result.NO; + } + } + catch (SignatureException ex) { + return Result.NO; + } + } + + private static String getSignatureAlgorithm(String keyAlgorithm) { + // https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html#signature-algorithms + // https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html#keypairgenerator-algorithms + return switch (keyAlgorithm) { + case "RSA" -> "SHA256withRSA"; + case "DSA" -> "SHA256withDSA"; + case "EC" -> "SHA256withECDSA"; + case "EdDSA" -> "EdDSA"; + default -> null; + }; + } + + enum Result { + + YES, NO, UNKNOWN + + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreBundle.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreBundle.java index 2500307669..b71750f361 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreBundle.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ssl/pem/PemSslStoreBundle.java @@ -16,12 +16,16 @@ package org.springframework.boot.ssl.pem; +import java.io.IOException; import java.security.KeyStore; import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import org.springframework.boot.ssl.SslStoreBundle; +import org.springframework.boot.ssl.pem.KeyVerifier.Result; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -71,8 +75,24 @@ public class PemSslStoreBundle implements SslStoreBundle { */ public PemSslStoreBundle(PemSslStoreDetails keyStoreDetails, PemSslStoreDetails trustStoreDetails, String keyAlias, String keyPassword) { - this.keyStore = createKeyStore("key", keyStoreDetails, keyAlias, keyPassword); - this.trustStore = createKeyStore("trust", trustStoreDetails, keyAlias, keyPassword); + this(keyStoreDetails, trustStoreDetails, keyAlias, keyPassword, false); + } + + /** + * Create a new {@link PemSslStoreBundle} instance. + * @param keyStoreDetails the key store details + * @param trustStoreDetails the trust store details + * @param keyAlias the key alias to use or {@code null} to use a default alias + * @param keyPassword the password to use for the key + * @param verifyKeys whether to verify that the private key matches the public key + * @since 3.2.0 + */ + public PemSslStoreBundle(PemSslStoreDetails keyStoreDetails, PemSslStoreDetails trustStoreDetails, String keyAlias, + String keyPassword, boolean verifyKeys) { + this.keyStore = createKeyStore("key", keyStoreDetails, (keyAlias != null) ? keyAlias : DEFAULT_KEY_ALIAS, + keyPassword, verifyKeys); + this.trustStore = createKeyStore("trust", trustStoreDetails, (keyAlias != null) ? keyAlias : DEFAULT_KEY_ALIAS, + keyPassword, verifyKeys); } @Override @@ -90,20 +110,25 @@ public class PemSslStoreBundle implements SslStoreBundle { return this.trustStore; } - private KeyStore createKeyStore(String name, PemSslStoreDetails details, String alias, String keyPassword) { + private static KeyStore createKeyStore(String name, PemSslStoreDetails details, String keyAlias, String keyPassword, + boolean verifyKeys) { if (details == null || details.isEmpty()) { return null; } try { Assert.notNull(details.certificate(), "Certificate content must not be null"); - String type = (!StringUtils.hasText(details.type())) ? KeyStore.getDefaultType() : details.type(); - KeyStore store = KeyStore.getInstance(type); - store.load(null); - String certificateContent = PemContent.load(details.certificate()); - String privateKeyContent = PemContent.load(details.privateKey()); - X509Certificate[] certificates = PemCertificateParser.parse(certificateContent); - PrivateKey privateKey = PemPrivateKeyParser.parse(privateKeyContent, details.privateKeyPassword()); - addCertificates(store, certificates, privateKey, (alias != null) ? alias : DEFAULT_KEY_ALIAS, keyPassword); + KeyStore store = createKeyStore(details); + X509Certificate[] certificates = loadCertificates(details); + PrivateKey privateKey = loadPrivateKey(details); + if (privateKey != null) { + if (verifyKeys) { + verifyKeys(privateKey, certificates); + } + addPrivateKey(store, privateKey, keyAlias, keyPassword, certificates); + } + else { + addCertificates(store, certificates, keyAlias); + } return store; } catch (Exception ex) { @@ -111,17 +136,48 @@ public class PemSslStoreBundle implements SslStoreBundle { } } - private void addCertificates(KeyStore keyStore, X509Certificate[] certificates, PrivateKey privateKey, String alias, - String keyPassword) throws KeyStoreException { - if (privateKey != null) { - keyStore.setKeyEntry(alias, privateKey, (keyPassword != null) ? keyPassword.toCharArray() : null, - certificates); - } - else { - for (int index = 0; index < certificates.length; index++) { - keyStore.setCertificateEntry(alias + "-" + index, certificates[index]); + private static void verifyKeys(PrivateKey privateKey, X509Certificate[] certificates) { + KeyVerifier keyVerifier = new KeyVerifier(); + // Key should match one of the certificates + for (X509Certificate certificate : certificates) { + Result result = keyVerifier.matches(privateKey, certificate.getPublicKey()); + if (result == Result.YES) { + return; } } + throw new IllegalStateException("Private key matches none of the certificates"); + } + + private static PrivateKey loadPrivateKey(PemSslStoreDetails details) { + String privateKeyContent = PemContent.load(details.privateKey()); + return PemPrivateKeyParser.parse(privateKeyContent, details.privateKeyPassword()); + } + + private static X509Certificate[] loadCertificates(PemSslStoreDetails details) { + String certificateContent = PemContent.load(details.certificate()); + X509Certificate[] certificates = PemCertificateParser.parse(certificateContent); + Assert.state(certificates != null && certificates.length > 0, "Loaded certificates are empty"); + return certificates; + } + + private static KeyStore createKeyStore(PemSslStoreDetails details) + throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { + String type = StringUtils.hasText(details.type()) ? details.type() : KeyStore.getDefaultType(); + KeyStore store = KeyStore.getInstance(type); + store.load(null); + return store; + } + + private static void addPrivateKey(KeyStore keyStore, PrivateKey privateKey, String alias, String keyPassword, + X509Certificate[] certificates) throws KeyStoreException { + keyStore.setKeyEntry(alias, privateKey, (keyPassword != null) ? keyPassword.toCharArray() : null, certificates); + } + + private static void addCertificates(KeyStore keyStore, X509Certificate[] certificates, String alias) + throws KeyStoreException { + for (int index = 0; index < certificates.length; index++) { + keyStore.setCertificateEntry(alias + "-" + index, certificates[index]); + } } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/KeyVerifierTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/KeyVerifierTests.java new file mode 100644 index 0000000000..4f681ce77f --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/KeyVerifierTests.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.ssl.pem; + +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.ECGenParameterSpec; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Named; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import org.springframework.boot.ssl.pem.KeyVerifier.Result; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link KeyVerifier}. + * + * @author Moritz Halbritter + */ +class KeyVerifierTests { + + private static final List ALGORITHMS = List.of(Algorithm.of("RSA"), Algorithm.of("DSA"), + Algorithm.of("ed25519"), Algorithm.of("ed448"), Algorithm.ec("secp256r1"), Algorithm.ec("secp521r1")); + + private final KeyVerifier keyVerifier = new KeyVerifier(); + + @ParameterizedTest(name = "{0}") + @MethodSource("arguments") + void test(PrivateKey privateKey, PublicKey publicKey, List invalidPublicKeys) { + assertThat(this.keyVerifier.matches(privateKey, publicKey)).isEqualTo(Result.YES); + for (PublicKey invalidPublicKey : invalidPublicKeys) { + assertThat(this.keyVerifier.matches(privateKey, invalidPublicKey)).isEqualTo(Result.NO); + } + } + + static Stream arguments() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { + List keyPairs = new LinkedList<>(); + for (Algorithm algorithm : ALGORITHMS) { + KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm.name()); + if (algorithm.spec() != null) { + generator.initialize(algorithm.spec()); + } + keyPairs.add(generator.generateKeyPair()); + keyPairs.add(generator.generateKeyPair()); + } + return keyPairs.stream() + .map((kp) -> Arguments.arguments(Named.named(kp.getPrivate().getAlgorithm(), kp.getPrivate()), + kp.getPublic(), without(keyPairs, kp).map(KeyPair::getPublic).toList())); + } + + private static Stream without(List keyPairs, KeyPair without) { + return keyPairs.stream().filter((kp) -> !kp.equals(without)); + } + + private record Algorithm(String name, AlgorithmParameterSpec spec) { + static Algorithm of(String name) { + return new Algorithm(name, null); + } + + static Algorithm ec(String curve) { + return new Algorithm("EC", new ECGenParameterSpec(curve)); + } + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/PemSslStoreBundleTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/PemSslStoreBundleTests.java index 29c22a27e0..cdb30bbc50 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/PemSslStoreBundleTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ssl/pem/PemSslStoreBundleTests.java @@ -24,12 +24,14 @@ import org.junit.jupiter.api.Test; import org.springframework.util.function.ThrowingConsumer; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; /** * Tests for {@link PemSslStoreBundle}. * * @author Scott Frederick * @author Phillip Webb + * @author Moritz Halbritter */ class PemSslStoreBundleTests { @@ -131,6 +133,34 @@ class PemSslStoreBundleTests { .satisfies(storeContainingCertAndKey("test-alias", "keysecret".toCharArray())); } + @Test + void shouldVerifyKeysIfEnabled() { + PemSslStoreDetails keyStoreDetails = PemSslStoreDetails + .forCertificate("classpath:org/springframework/boot/ssl/pem/key1.crt") + .withPrivateKey("classpath:org/springframework/boot/ssl/pem/key1.pem"); + PemSslStoreBundle bundle = new PemSslStoreBundle(keyStoreDetails, null, "test-alias", "keysecret", true); + assertThat(bundle.getKeyStore()).satisfies(storeContainingCertAndKey("test-alias", "keysecret".toCharArray())); + } + + @Test + void shouldVerifyKeysIfEnabledAndCertificateChainIsUsed() { + PemSslStoreDetails keyStoreDetails = PemSslStoreDetails + .forCertificate("classpath:org/springframework/boot/ssl/pem/key2-chain.crt") + .withPrivateKey("classpath:org/springframework/boot/ssl/pem/key2.pem"); + PemSslStoreBundle bundle = new PemSslStoreBundle(keyStoreDetails, null, "test-alias", "keysecret", true); + assertThat(bundle.getKeyStore()).satisfies(storeContainingCertAndKey("test-alias", "keysecret".toCharArray())); + } + + @Test + void shouldFailIfVerifyKeysIsEnabledAndKeysDontMatch() { + PemSslStoreDetails keyStoreDetails = PemSslStoreDetails + .forCertificate("classpath:org/springframework/boot/ssl/pem/key2.crt") + .withPrivateKey("classpath:org/springframework/boot/ssl/pem/key1.pem"); + assertThatIllegalStateException() + .isThrownBy(() -> new PemSslStoreBundle(keyStoreDetails, null, null, null, true)) + .withMessageContaining("Private key matches none of the certificates"); + } + private Consumer storeContainingCert(String keyAlias) { return storeContainingCert(KeyStore.getDefaultType(), keyAlias); } diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/ca.crt b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/ca.crt new file mode 100644 index 0000000000..b9343e01ef --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/ca.crt @@ -0,0 +1,19 @@ +-----BEGIN TRUSTED CERTIFICATE----- +MIIDIDCCAgsCFH3lh1RXOEy2ESqUPyzb+9zxMYUnMA0GCSqGSIb3DQEBCwUAME8x +CzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl +ZmF1bHQgQ29tcGFueSBMdGQxCzAJBgNVBAMMAkNBMCAXDTIzMTAwNTA3MjU1M1oY +DzIxMjMwOTExMDcyNTUzWjBPMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVs +dCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMQswCQYDVQQDDAJD +QTCCAR4wDQYJKoZIhvcNAQEBBQADggELADCCAQYCgf4NNpc+6B3qvwKcRYgoXmJ4 +3wyWktBK7BdShz/YnW1OlFZ+R845ZiDw0KdzElZWkYqn+BYJus6lPIS5dfLcrGSf +a1e8IK02RpBiY/WJvupetnSk8gKA7emF94NlV4gXr4ICJAhXvXUFyBLpdEUE/lcg +lgCbVJzs5jWUnffEF9mrClzzo0+iXw34zwmyYyBTFmlOEr+QUEdAb6Lr/klpTVit +as2Ddg1QT4EaSIdTEpkVRZp2dyYVdqSxpaBq21xg0viDHsYQrP96IfacmUB7kFFn +HsnptDHFvJj2WSQDX+PRS7tLl4mmfizZg80eGfLD22ShNspRSGnbJc0OzegPiwID +AQABMA0GCSqGSIb3DQEBCwUAA4H/AAnC+FQqdeJaG5I7R+pNjgKplL2UsxW983kA +CVVkv/Dt0+4rbPC67o9/8Tr+g4eo/wUntMNo2ghF3oBItGr7pJE16zPiLwIvha9c +8BDhCEZWyhz3vkamZUi19lOnkm3zTmmDE/nX4WYH6CL4UWjxvniZYwW8AdVSnFXY +ncriuvfliLa3dw1SJ7FtxdcBn4yfzrZWcY+psYNHpftLGYRmQF/VCDSB9EAIEggr +yBcP749u2y8s44WvKAnnwfLcALIrylY25zN0pao/l2X8HI6qHUeA/QbbEBpDoQvR +du/rgaHCVvFFxATefhBJ0CUA1Nn5nrGwyRTKnZWtR080qwUp +-----END TRUSTED CERTIFICATE----- diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/ca.pem b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/ca.pem new file mode 100644 index 0000000000..c5102f84da --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/ca.pem @@ -0,0 +1,27 @@ +-----BEGIN PRIVATE KEY----- +MIIEqQIBADANBgkqhkiG9w0BAQEFAASCBJMwggSPAgEAAoH+DTaXPugd6r8CnEWI +KF5ieN8MlpLQSuwXUoc/2J1tTpRWfkfOOWYg8NCncxJWVpGKp/gWCbrOpTyEuXXy +3Kxkn2tXvCCtNkaQYmP1ib7qXrZ0pPICgO3phfeDZVeIF6+CAiQIV711BcgS6XRF +BP5XIJYAm1Sc7OY1lJ33xBfZqwpc86NPol8N+M8JsmMgUxZpThK/kFBHQG+i6/5J +aU1YrWrNg3YNUE+BGkiHUxKZFUWadncmFXaksaWgattcYNL4gx7GEKz/eiH2nJlA +e5BRZx7J6bQxxbyY9lkkA1/j0Uu7S5eJpn4s2YPNHhnyw9tkoTbKUUhp2yXNDs3o +D4sCAwEAAQKB/goGHht1EC0kFyDihvbJE79Kx0v7uNT94nuTa1Yzp9bzJeLLKqHU +3qySPlZH1QP7icr/pAhhlZ85GB9yYXoTtopSbs6jo4QHaEWcO4vyL+8GT9tKVafl +1UDyktXw36fIV8Kz/zhA3GQ0clR1Bl9RbFumMHOmbx4xTvieFnbG+TQ2THfFccGS +jCO6+dab6daXs8sBt0rGMh72utIISVsFJc7v3B8BpaNOI4iBMciRSyZeE4Vw/lRg +e3iErAVUmUjBrUK/wBy/l9cbbpkp+rvhQpmTIPtKd5f29AQNL7p6V+2+yRb2woRk +0i1HwOHGOhiCTxXZB9/nZykaT/T2+J9BAn8+DEWCRcfifyNEyuE54G6BvLvgGTgs ++kXWS7p0+wO9CFBDZARu/MXFEfcWt4ZTIj8HtMiKhxNbC1LiGtQnJoLV6AM75E5Q +toh/xyYOnHbhnbhsSNcpJk5iIdqQE6hWh+rYXFr1aJFMRZaWRkcUG8iIxWQQjRvw +qxLm9GQtEhF7An82hAlPCDs+6kT1otBEN8vGaW8qkxWYJf6kSd/I0/TEKRYpIwBa +Ist2BN5GrJTitKhzQIq2ZyT2byHxS0VIvInZJ6sFC+V6fHYpzWbS3zkBy2zswfAZ +UYrdjLVv16qZYsdjUnhkyUaBbBXnrTPlPzxXvgTeqJeJ5tbR6wgeqPUxAn8lcQxE +t00N/UBQE8jjPu4QNc59RVqjsYaQ8POcAZjY6fpdIC6Ytsm0yMl8mNRiuCimws28 +4hOo/eVO8XeSBGgxIidJbdRgWjV2PbtWV85ZCO6v0Sic+TOVfe5AwMv1I2FwnBJ7 +QlVjXB6podDkbnuNJOfkIPJ6QRFP8qu8ksmfAn8mttuZeYIBawLv4eC/IVSgIc3l +UTC7rPfKGgBHMWaYS4lGS2n7mMwektR7IiJVYPBjcIlRgaw5KbDUF50rS2Elissj +uVANDQgpJYoI5KcqRBmlhRCKGmNgdIWA2Ip5hTGNskp3YIymamif71t0SNUEhpgU +u2tqbjlON/e7NkdxAn8VdVYq+4sAWRdU4VJqqyf8dyBx68sysvY6HYlKS2bpfu3C +J3gbPximDZhzMvKx2/CAzMbAT3anyr/DiUImk+QdWSmht+1SLH7A14MDjzQ0D5xt +GgPqWn7PtcJojFMjc/o5/fKgFf4CYkJhv2KycX9UeldBxpqNpNigzFWBLdtu +-----END PRIVATE KEY----- diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key1.crt b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key1.crt new file mode 100644 index 0000000000..e381ab69b3 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key1.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJjCCAhECFHuJXZO0JDPtCSc1/r0llpyc/j9TMA0GCSqGSIb3DQEBCwUAME8x +CzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl +ZmF1bHQgQ29tcGFueSBMdGQxCzAJBgNVBAMMAkNBMCAXDTIzMTAwNTA3Mjg0NVoY +DzIxMjMwOTExMDcyODQ1WjBRMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVs +dCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMQ0wCwYDVQQDDARr +ZXkxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoYU2afupPq/b6PIy +6MWDOMRdJk5uW51lrw6oudXpWlUQMXKdsaZT4sqbgjGLggfo7WWsPeCzQN3kIX3T +OqBog5EMkXnlQhAfP2Htj0uXPFj97leZ+FqJrzgPnZY8wSqDXfy9/ycR3PgWjRsS +GZJb05hTNVGTU2vpNQDDo+XBKgybB0afGU8Nk/InWfs1xd/Jv0YcVADQiQEmg41w +g18B3LMIBZPWIJUQ1b7wMlhxWaCNXHfB1bUTIYCUAUOZyEaxPaOOiJo32xKmqOlU +TCLM8zgWCBCEgHtQwSD0GMLhUarLPNE5GP3yo5qHBYqOque7BBjP4e58r6wAyBoe +7kMYRQIDAQABMA0GCSqGSIb3DQEBCwUAA4H/AAMIYpTDxgQwpfk+U1IhkqJjb+Uh +hj6KlT5TEdpn/saGYLZQECZAO21MWrUDTsV2Pax2Ee8ezarCg8Cthu4YOtPauPaL +XpyrIagUOgrDcmXr6QxMKUqifiMurLRFaAS7mWXp0TAFNgzDg3WvF9zMJgkjUp/O +gNSG9U7kXuFfxpVtoalyC2C3g3UeieVXSek3a28h5c/0/DomHqLbyqZh5rYwAJ7C +q1bqA5TnZNVvV731SVueycj9+5PKHKG6eeRRh7roZ34l54O9adNEeDAF0Lqn4sbn +a/h4GPK/u6J6Y3nwrdajipZ2DmfiQwoimxprMGNQKuKA0lc025SGHNno +-----END CERTIFICATE----- diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key1.pem b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key1.pem new file mode 100644 index 0000000000..197eabb172 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key1.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQChhTZp+6k+r9vo +8jLoxYM4xF0mTm5bnWWvDqi51elaVRAxcp2xplPiypuCMYuCB+jtZaw94LNA3eQh +fdM6oGiDkQyReeVCEB8/Ye2PS5c8WP3uV5n4WomvOA+dljzBKoNd/L3/JxHc+BaN +GxIZklvTmFM1UZNTa+k1AMOj5cEqDJsHRp8ZTw2T8idZ+zXF38m/RhxUANCJASaD +jXCDXwHcswgFk9YglRDVvvAyWHFZoI1cd8HVtRMhgJQBQ5nIRrE9o46ImjfbEqao +6VRMIszzOBYIEISAe1DBIPQYwuFRqss80TkY/fKjmocFio6q57sEGM/h7nyvrADI +Gh7uQxhFAgMBAAECggEABUfEGCHkjgqUv2BPnsF6QTxWKT7uJ6uVG+x4Qp8GInBe +d6deFWUxH9xsygxRmb4ldMFaqKk0Yv3+C8Q/yA5fbFGtHgJkpsy9IMbUS9d2ScBF +COovO+nFz4cfJ5E2SkBYDBYLphBCar1ni1RjupdIzjmQGtGgZd1EwflU7AJCVtwG +S7ltIs2nSOqUFGTfjb9j0NiATZvWTDRtavNMhyrZplKK6M6VoH1ZcnmcvEfF7j5L +oSmXrNKYs4iKn1qKypykfCQoEFK0/EEjj5EdnPaSeI9EERrZK1QnHafB2qK38LSr +8cGaWH24mPW6c/26bDQnHkN3SqKLCODXZMBGhPlLDwKBgQDdMqOzRR3SpTx7KPqp +h+P0diBZb1e6c+Ob0lXD/rfJEtkAqyFLqpi8hN9xodxw++JYbhC69kJE7VWtQLIt +Lc+DG72KTS/cbpnvERL1+AoM0TRbO9Ds9aFP4+Zmm/VDxi9rR5yTgl9iAHJ46VrE +BhnG8JQPBm4n5JU5/wJ9qCQCywKBgQC67uWchaewzDHCiefhTVgwTm1BmHiV/OR4 +50Je2x3GPW6VJGFnBjVzlScKrNyFeOYwscvVS8pTmFP8c5laTbQMC3pVqiWs28Ip +6sy6cXfepVyc0njLFGbiek8ab0rjVYU27D0O9tucrxDx4pKOurilds1Gbm4HjfyE +R7pWn/AfLwKBgQC+5wJzKLaJYsQlAwP6pmYtSHm41ihfqb8Jb2lHwyD4r4SLWCZf +OHejVAXH+0rWU/1QFoXn5brh4/cqlIhyB3RtkdZucxlYZDgEJLc5g32g/Dj0eFZi ++8bhvS3O5tCxUm0AaIiQolcRrJMfGT6VqTI8CMuvf/w3/8ZujFCpBCE4KwKBgBiw +lQMnZA6l6ayYKlhHru4ybZvMV6D31fViFhIRPs2AL6rjMzo4R7cMbCusyTOX1E96 +LEHv0LlZ1T3yxr52pOEyYuYNowxBulNu/7tgYUS28pSD+BBakXw4S1pieLGuCfpH +GYlwcXEwbjyEgHb5konINzSmQUIeLswJ7UKjvUNhAoGAXmXvyHqdL04SD99G3B/5 ++azzzAVR1fvGYOvq+/hWZMG5PS0kx2V3txCVyY8E1/lCysp9BuUHtW+vOS8YGhAT +wkZ/X9igZteQvvdVw+E5CXS05b4EBI+7ZViL9ulXFZ4YC70lKcUE52bmaPM+onQJ +Y1s9JWTe2EAkxsuxm+hkjo0= +-----END PRIVATE KEY----- diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2-chain.crt b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2-chain.crt new file mode 100644 index 0000000000..3b55b95a96 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2-chain.crt @@ -0,0 +1,38 @@ +-----BEGIN CERTIFICATE----- +MIIDJjCCAhECFFjLlXVdTxDdLlCifzrA0dTHHJ2mMA0GCSqGSIb3DQEBCwUAME8x +CzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl +ZmF1bHQgQ29tcGFueSBMdGQxCzAJBgNVBAMMAkNBMCAXDTIzMTAwNTA3Mjg1MFoY +DzIxMjMwOTExMDcyODUwWjBRMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVs +dCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMQ0wCwYDVQQDDARr +ZXkyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAspCMUdFGyKkgpMbW ++UwSg4fdKM4qLSH7voTdsdVM9aAvLvYjBQ4gpORxDZNfUz67R0Ua0/oJt9jD49Wp +qcq+tDOnp0dPtn2hFluV5PxM6d+MCSx/frPsfvyt9234okLL1zdLDNFYEbLhSPjA +ku3vHw/OwlJOxCRwTkPqcElIV4+IvIbzAgSffyokzm/wKVKEhoT6NcfeU+6wCkTu +al1X8loJ+27N6jN13oGZfH7EveBqgR8rPs55+54S/OcVG/uqL9ggOGRJiIZ3jUBk +m5cN27wKkaNg/CQwa1UjcU4qshVpknHw1dpgJ2Gbs/yUphwpEZl/FTsZFcK1KCHD +rOp3PQIDAQABMA0GCSqGSIb3DQEBCwUAA4H/AAFmEq86broBFxs0cpImaM884PBT +bvJBSsFhsOg6mi4Gt01G/lPSj/ExNtH3G5bytCYAPaRxNx/dCs7uON3p86ta4zL8 +2PxgyhX1oY/GG63ETwn5s3GKpRaGTNVDWvPIM9RX6+bvX/wOg8eYXVaQlG5XYadC +Ms9lWqHaM1C/iLGNmUTGcdbvhnmQDky2CwPNm+lXogSWbrsGpAmCkXJD1H+0Mx8I +wjDVtGLBwr/8oXI8WbhvISMnS9+dd7+GLm6mU+14Kswi5I7EmBmREvkswi2IVJ6M +GL7EY3qA6iqJWqsseYyLxiMr3nBT0SETphzoDanUQI1/jXQPrWIyjqvs +-----END CERTIFICATE----- +-----BEGIN TRUSTED CERTIFICATE----- +MIIDIDCCAgsCFH3lh1RXOEy2ESqUPyzb+9zxMYUnMA0GCSqGSIb3DQEBCwUAME8x +CzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl +ZmF1bHQgQ29tcGFueSBMdGQxCzAJBgNVBAMMAkNBMCAXDTIzMTAwNTA3MjU1M1oY +DzIxMjMwOTExMDcyNTUzWjBPMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVs +dCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMQswCQYDVQQDDAJD +QTCCAR4wDQYJKoZIhvcNAQEBBQADggELADCCAQYCgf4NNpc+6B3qvwKcRYgoXmJ4 +3wyWktBK7BdShz/YnW1OlFZ+R845ZiDw0KdzElZWkYqn+BYJus6lPIS5dfLcrGSf +a1e8IK02RpBiY/WJvupetnSk8gKA7emF94NlV4gXr4ICJAhXvXUFyBLpdEUE/lcg +lgCbVJzs5jWUnffEF9mrClzzo0+iXw34zwmyYyBTFmlOEr+QUEdAb6Lr/klpTVit +as2Ddg1QT4EaSIdTEpkVRZp2dyYVdqSxpaBq21xg0viDHsYQrP96IfacmUB7kFFn +HsnptDHFvJj2WSQDX+PRS7tLl4mmfizZg80eGfLD22ShNspRSGnbJc0OzegPiwID +AQABMA0GCSqGSIb3DQEBCwUAA4H/AAnC+FQqdeJaG5I7R+pNjgKplL2UsxW983kA +CVVkv/Dt0+4rbPC67o9/8Tr+g4eo/wUntMNo2ghF3oBItGr7pJE16zPiLwIvha9c +8BDhCEZWyhz3vkamZUi19lOnkm3zTmmDE/nX4WYH6CL4UWjxvniZYwW8AdVSnFXY +ncriuvfliLa3dw1SJ7FtxdcBn4yfzrZWcY+psYNHpftLGYRmQF/VCDSB9EAIEggr +yBcP749u2y8s44WvKAnnwfLcALIrylY25zN0pao/l2X8HI6qHUeA/QbbEBpDoQvR +du/rgaHCVvFFxATefhBJ0CUA1Nn5nrGwyRTKnZWtR080qwUp +-----END TRUSTED CERTIFICATE----- diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2.crt b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2.crt new file mode 100644 index 0000000000..1278826278 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJjCCAhECFFjLlXVdTxDdLlCifzrA0dTHHJ2mMA0GCSqGSIb3DQEBCwUAME8x +CzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl +ZmF1bHQgQ29tcGFueSBMdGQxCzAJBgNVBAMMAkNBMCAXDTIzMTAwNTA3Mjg1MFoY +DzIxMjMwOTExMDcyODUwWjBRMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVs +dCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMQ0wCwYDVQQDDARr +ZXkyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAspCMUdFGyKkgpMbW ++UwSg4fdKM4qLSH7voTdsdVM9aAvLvYjBQ4gpORxDZNfUz67R0Ua0/oJt9jD49Wp +qcq+tDOnp0dPtn2hFluV5PxM6d+MCSx/frPsfvyt9234okLL1zdLDNFYEbLhSPjA +ku3vHw/OwlJOxCRwTkPqcElIV4+IvIbzAgSffyokzm/wKVKEhoT6NcfeU+6wCkTu +al1X8loJ+27N6jN13oGZfH7EveBqgR8rPs55+54S/OcVG/uqL9ggOGRJiIZ3jUBk +m5cN27wKkaNg/CQwa1UjcU4qshVpknHw1dpgJ2Gbs/yUphwpEZl/FTsZFcK1KCHD +rOp3PQIDAQABMA0GCSqGSIb3DQEBCwUAA4H/AAFmEq86broBFxs0cpImaM884PBT +bvJBSsFhsOg6mi4Gt01G/lPSj/ExNtH3G5bytCYAPaRxNx/dCs7uON3p86ta4zL8 +2PxgyhX1oY/GG63ETwn5s3GKpRaGTNVDWvPIM9RX6+bvX/wOg8eYXVaQlG5XYadC +Ms9lWqHaM1C/iLGNmUTGcdbvhnmQDky2CwPNm+lXogSWbrsGpAmCkXJD1H+0Mx8I +wjDVtGLBwr/8oXI8WbhvISMnS9+dd7+GLm6mU+14Kswi5I7EmBmREvkswi2IVJ6M +GL7EY3qA6iqJWqsseYyLxiMr3nBT0SETphzoDanUQI1/jXQPrWIyjqvs +-----END CERTIFICATE----- diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2.pem b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2.pem new file mode 100644 index 0000000000..9e21a1c3f4 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/ssl/pem/key2.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCykIxR0UbIqSCk +xtb5TBKDh90oziotIfu+hN2x1Uz1oC8u9iMFDiCk5HENk19TPrtHRRrT+gm32MPj +1ampyr60M6enR0+2faEWW5Xk/Ezp34wJLH9+s+x+/K33bfiiQsvXN0sM0VgRsuFI ++MCS7e8fD87CUk7EJHBOQ+pwSUhXj4i8hvMCBJ9/KiTOb/ApUoSGhPo1x95T7rAK +RO5qXVfyWgn7bs3qM3XegZl8fsS94GqBHys+znn7nhL85xUb+6ov2CA4ZEmIhneN +QGSblw3bvAqRo2D8JDBrVSNxTiqyFWmScfDV2mAnYZuz/JSmHCkRmX8VOxkVwrUo +IcOs6nc9AgMBAAECggEAPN9dDolG1aIeYD3uzCa8Sv2WjdIWe7NRlEXMI9MgvL1i +SGKdVpxV0ZCU37llLkY85tNujWP4SyXIxdMxVxIoR9syJKsBSCd0sl//bgP6nmHY +Zco3HnTswu+VyLtDHuGhhtkxKwn0uXffKBaw44XcVhz38bPIaUI4zN2HPscks8BG +j2MEl0N8P/TVrTkhgdjfoRi73VAisrEe+1wCg74BT7cmR8fEr7iNFrv955sdPGdw +UTmx8U26++wbeYQs1ZE1713SYnRQuCUFs5GGjzOhNFi27zuhI6TafoVm9PO4j+ZC +JUKTyUTBUsRMvm9z1IoHdjM8yInAv2g0J1bAeCTY+wKBgQDuMNMbNVoiXRKsSUry +22T3W6HVLfLNKiYMNxsAkJjOiyyJcC+yg9BErn/haIHSafD2WmuWbW5ASViyl6fn +D8qMluTwEaSrTgHXWI4ahWyapDShDQYp1s4dB75Aa/LVcFCay54YEtyCPzCPlj1K +jz5OBV14NEVVA2cf59fIc/LXCwKBgQC/6m3TefUp5jnN/QUOx2OtZo8Y1pVrsuMB +AuTtb21Khxn/86ZpVzySzg79/DkSNf9/sZhzj0IkviWNP5S8iAAaFC1q08CYhdCX +d7tVnHlzpZmmoHUhG6dlJZayr1duZrURp2rP18+wIsKiFRImAyjc6yswVRpZgAiG +gOkHCB231wKBgGlwXZMWy/6YOtLfYvkcm5ZQDtSCkY+2j78qiZ53Y91SiHWSntqk +NQaiRGOw0n8lfJBhOG0PphV5InV0YtQLDnurtE59UOqwDmqYfddJpujRtaZxUIAm +4XjCW7rCzm0jWdscNbCscMaLWGDHffxKaqc5AsZaRTK73eOmysOmaCI/AoGAf/yd +RZ1dzJWHE0Kb7uE2LlvpLo1clLh1/ySo+1eGMV+sDS+2WSYedWEKSoO8o9JzE/ui +Sd7OI6bTcEFotdqVBs9SAp45IP6Mv5bPziZOMLvNnnv/4RaKKkBJId0hl7TTKHTY +HMg176ce2eznb4ZH6BzFbrQyoGFsThcGUPQurX0CgYBYtkDTp21TI1nuak7xpMIY +BJQpqF5ahBf/+QYWtL0f3ca9MO2++zv5/XXitvt48cY1bCHNrVvSHgRzwSrOorZA +5u7a5zyvfXjY3LY3k0VHddaVjU0mHsjx/1ux0wO2v8wQjOVZpT7XweB3WlUEGV7C +5T/p+rmGg5Y5dTKUVCyvbQ== +-----END PRIVATE KEY-----