Skip to content

Commit ef4b097

Browse files
committed
Fix loading of PKCS#8 PEM encoded EC and DSA keys for buildpack
Polish and port support for PKCS#8 PEM encoded EC and DSA keys to the buildpack code. See gh-35322
1 parent e9c4a5d commit ef4b097

File tree

4 files changed

+121
-41
lines changed

4 files changed

+121
-41
lines changed

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParser.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.security.GeneralSecurityException;
2525
import java.security.KeyFactory;
2626
import java.security.PrivateKey;
27+
import java.security.spec.InvalidKeySpecException;
2728
import java.security.spec.PKCS8EncodedKeySpec;
2829
import java.util.ArrayList;
2930
import java.util.Collections;
@@ -39,6 +40,7 @@
3940
*
4041
* @author Scott Frederick
4142
* @author Phillip Webb
43+
* @author Moritz Halbritter
4244
*/
4345
final class PrivateKeyParser {
4446

@@ -59,9 +61,9 @@ final class PrivateKeyParser {
5961
private static final List<PemParser> PEM_PARSERS;
6062
static {
6163
List<PemParser> parsers = new ArrayList<>();
62-
parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, "RSA", PrivateKeyParser::createKeySpecForPkcs1));
63-
parsers.add(new PemParser(EC_HEADER, EC_FOOTER, "EC", PrivateKeyParser::createKeySpecForEc));
64-
parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, "RSA", PKCS8EncodedKeySpec::new));
64+
parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, PrivateKeyParser::createKeySpecForPkcs1, "RSA"));
65+
parsers.add(new PemParser(EC_HEADER, EC_FOOTER, PrivateKeyParser::createKeySpecForEc, "EC"));
66+
parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, PKCS8EncodedKeySpec::new, "RSA", "EC", "DSA"));
6567
PEM_PARSERS = Collections.unmodifiableList(parsers);
6668
}
6769

@@ -141,14 +143,14 @@ private static class PemParser {
141143

142144
private final Pattern pattern;
143145

144-
private final String algorithm;
145-
146146
private final Function<byte[], PKCS8EncodedKeySpec> keySpecFactory;
147147

148-
PemParser(String header, String footer, String algorithm,
149-
Function<byte[], PKCS8EncodedKeySpec> keySpecFactory) {
148+
private final String[] algorithms;
149+
150+
PemParser(String header, String footer, Function<byte[], PKCS8EncodedKeySpec> keySpecFactory,
151+
String... algorithms) {
150152
this.pattern = Pattern.compile(header + BASE64_TEXT + footer, Pattern.CASE_INSENSITIVE);
151-
this.algorithm = algorithm;
153+
this.algorithms = algorithms;
152154
this.keySpecFactory = keySpecFactory;
153155
}
154156

@@ -165,8 +167,15 @@ private static byte[] decodeBase64(String content) {
165167
private PrivateKey parse(byte[] bytes) {
166168
try {
167169
PKCS8EncodedKeySpec keySpec = this.keySpecFactory.apply(bytes);
168-
KeyFactory keyFactory = KeyFactory.getInstance(this.algorithm);
169-
return keyFactory.generatePrivate(keySpec);
170+
for (String algorithm : this.algorithms) {
171+
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
172+
try {
173+
return keyFactory.generatePrivate(keySpec);
174+
}
175+
catch (InvalidKeySpecException ex) {
176+
}
177+
}
178+
return null;
170179
}
171180
catch (GeneralSecurityException ex) {
172181
throw new IllegalArgumentException("Unexpected key format", ex);

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PemFileWriter.java

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* Utility to write certificate and key PEM files for testing.
2929
*
3030
* @author Scott Frederick
31+
* @author Moritz Halbritter
3132
*/
3233
public class PemFileWriter {
3334

@@ -49,22 +50,6 @@ public class PemFileWriter {
4950
+ "zLEfeu6JPugAR71JYbc2CqGrMneSk1zT91EH6ohIz8OR5VNvzB7N7q65Ci7OFMPl\n"
5051
+ "ly6k3rHpMCBtHoyNFhNVfPLxGJ9VlWFKLgIAbCmL4OIQm1l6Fr1MSM38Zw==\n" + "-----END TRUSTED CERTIFICATE-----\n";
5152

52-
public static final String CA_PRIVATE_KEY = EXAMPLE_SECRET_QUALIFIER + "-----BEGIN PRIVATE KEY-----\n"
53-
+ "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANWM4sVhKMs63dtA\n"
54-
+ "tkdYI8jwqD3xS5RulGE8k9Lbnjcuso7+qmyfJXGYO+tejtyPS7jh4WYfVPnwgwoD\n"
55-
+ "34g3ciXwxFvz/nbDjBcjFFz6yT83tsj6Tp71fIieQzPd7nxFYQgssy3WLtD9j94V\n"
56-
+ "Nlvk9/yJvQwOxTjwNrxdUqyCdqrVAgMBAAECgYEAyJTlZ8nj3Eg1nLxCue6C5jmN\n"
57-
+ "fWkIuanH+zFAE/0utdxJ4WA4yYAOVo1MMr8FZwu9bzHTWe2yDnWnT5/ltPeHYX2X\n"
58-
+ "9Pg5cY0tjq07utaMwLKWgJ0Xoh2UpVM799t/rSvMWmLaZ2c8nipX+gQfYJFpX8Vg\n"
59-
+ "mR3QPxwdmNyFo13qif0CQQD4z2SqCfARuxscTCJDZ6wReikMQxaJvq74lPEtT26L\n"
60-
+ "rBr/bN+mG7+rMEHxs5wtU47aNjUKuVVC0Qfhsf95ahvHAkEA27inSlxrwGvhvFsD\n"
61-
+ "FWdgDsfYpPZdL4YgpVSEvcoypRGg2suJw2omcKcY56XpkmWUqZc06QirumtnEC0P\n"
62-
+ "HfnsgwJBAMVhEURrOc13FxytsQiz96atuF6H4htH79o3ndQKDXI0B/7VSd6maLjP\n"
63-
+ "QaESkTTL8qldE1r8h4zH8m6zHC4fZQUCQFWJ+8bdWC2fUlBr9jVc+26Fqvf92aVo\n"
64-
+ "yEjVMKBamYDd7gt/9fAX4UM2KmH0m4wc89VaQoT+lSyMJ6GKiToYVFUCQEXcyoeO\n"
65-
+ "zWqtSgEX/eXQXzmMKxYnjv1O//ba3Q7UiHd/XO5j4QXAJpcB6h0h00uC5KY2d0Zy\n" + "JQ1kB1C2l6l9tyc=\n"
66-
+ "-----END PRIVATE KEY-----";
67-
6853
public static final String CERTIFICATE = "-----BEGIN CERTIFICATE-----\n"
6954
+ "MIICjzCCAfgCAQEwDQYJKoZIhvcNAQEFBQAwgY8xCzAJBgNVBAYTAlVTMRMwEQYD\n"
7055
+ "VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQK\n"
@@ -101,6 +86,74 @@ public class PemFileWriter {
10186
+ "AwEHoUQDQgAE8y28khug747bA68M90IAMCPHAYyen+RsN6i84LORpNDUhv00QZWd\n"
10287
+ "hOhjWFCQjnewR98Y8pEb1fnORll4LhHPlQ==\n" + "-----END EC PRIVATE KEY-----";
10388

89+
public static final String PRIVATE_DSA_KEY = EXAMPLE_SECRET_QUALIFIER + "-----BEGIN PRIVATE KEY-----\n"
90+
+ "MIICXAIBADCCAjUGByqGSM44BAEwggIoAoIBAQCPeTXZuarpv6vtiHrPSVG28y7F\n"
91+
+ "njuvNxjo6sSWHz79NgbnQ1GpxBgzObgJ58KuHFObp0dbhdARrbi0eYd1SYRpXKwO\n"
92+
+ "jxSzNggooi/6JxEKPWKpk0U0CaD+aWxGWPhL3SCBnDcJoBBXsZWtzQAjPbpUhLYp\n"
93+
+ "H51kjviDRIZ3l5zsBLQ0pqwudemYXeI9sCkvwRGMn/qdgYHnM423krcw17njSVkv\n"
94+
+ "aAmYchU5Feo9a4tGU8YzRY+AOzKkwuDycpAlbk4/ijsIOKHEUOThjBopo33fXqFD\n"
95+
+ "3ktm/wSQPtXPFiPhWNSHxgjpfyEc2B3KI8tuOAdl+CLjQr5ITAV2OTlgHNZnAh0A\n"
96+
+ "uvaWpoV499/e5/pnyXfHhe8ysjO65YDAvNVpXQKCAQAWplxYIEhQcE51AqOXVwQN\n"
97+
+ "NNo6NHjBVNTkpcAtJC7gT5bmHkvQkEq9rI837rHgnzGC0jyQQ8tkL4gAQWDt+coJ\n"
98+
+ "syB2p5wypifyRz6Rh5uixOdEvSCBVEy1W4AsNo0fqD7UielOD6BojjJCilx4xHjG\n"
99+
+ "jQUntxyaOrsLC+EsRGiWOefTznTbEBplqiuH9kxoJts+xy9LVZmDS7TtsC98kOmk\n"
100+
+ "ltOlXVNb6/xF1PYZ9j897buHOSXC8iTgdzEpbaiH7B5HSPh++1/et1SEMWsiMt7l\n"
101+
+ "U92vAhErDR8C2jCXMiT+J67ai51LKSLZuovjntnhA6Y8UoELxoi34u1DFuHvF9ve\n"
102+
+ "BB4CHHBQgJ3ST6U8rIxoTqGe42TiVckPf1PoSiJy8GY=\n" + "-----END PRIVATE KEY-----\n";
103+
104+
public static final String PKCS8_PRIVATE_EC_NIST_P256_KEY = EXAMPLE_SECRET_QUALIFIER
105+
+ "-----BEGIN PRIVATE KEY-----\n" + "MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgd6SePFfpaTKFd1Gm\n"
106+
+ "+WeHZNkORkot5hx6X9elPdICL9ygCgYIKoZIzj0DAQehRANCAASnMAMgeFBv9ks0\n"
107+
+ "d0jP+utQ3mohwmxY93xljfaBofdg1IeHgDd4I4pBzPxEnvXrU3kcz+SgPZyH1ybl\n" + "P6mSXDXu\n"
108+
+ "-----END PRIVATE KEY-----\n";
109+
110+
public static final String PKCS8_PRIVATE_EC_NIST_P384_KEY = EXAMPLE_SECRET_QUALIFIER
111+
+ "-----BEGIN PRIVATE KEY-----\n" + "MIG/AgEAMBAGByqGSM49AgEGBSuBBAAiBIGnMIGkAgEBBDCexXiWKrtrqV1+d1Tv\n"
112+
+ "t1n5huuw2A+204mQHRuPL9UC8l0XniJjx/PVELCciyJM/7+gBwYFK4EEACKhZANi\n"
113+
+ "AASHEELZSdrHiSXqU1B+/jrOCr6yjxCMqQsetTb0q5WZdCXOhggGXfbzlRynqphQ\n"
114+
+ "i4G7azBUklgLaXfxN5eFk6C+E38SYOR7iippcQsSR2ZsCiTk7rnur4b40gQ7IgLA\n" + "/sU=\n"
115+
+ "-----END PRIVATE KEY-----\n";
116+
117+
public static final String PKCS8_PRIVATE_EC_PRIME256V1_KEY = EXAMPLE_SECRET_QUALIFIER
118+
+ "-----BEGIN PRIVATE KEY-----\n" + "MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg4dVuddgQ6enDvPPw\n"
119+
+ "Dd1mmS6FMm/kzTJjDVsltrNmRuSgCgYIKoZIzj0DAQehRANCAAR1WMrRADEaVj9m\n"
120+
+ "uoUfPhUefJK+lS89NHikQ0ZdkHkybyVKLFMLe1hCynhzpKQmnpgud3E10F0P2PZQ\n" + "L9RCEpGf\n"
121+
+ "-----END PRIVATE KEY-----\n";
122+
123+
public static final String PKCS8_PRIVATE_EC_SECP256R1_KEY = EXAMPLE_SECRET_QUALIFIER
124+
+ "-----BEGIN PRIVATE KEY-----\n" + "MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgU9+v5hUNnTKix8fe\n"
125+
+ "Pfz+NfXFlGxQZMReSCT2Id9PfKagCgYIKoZIzj0DAQehRANCAATeJg+YS4BrJ35A\n"
126+
+ "KgRlZ59yKLDpmENCMoaYUuWbQ9hqHzdybQGzQsrNJqgH0nzWghPwP4nFaLPN+pgB\n" + "bqiRgbjG\n"
127+
+ "-----END PRIVATE KEY-----\n";
128+
129+
public static final String PKCS8_PRIVATE_RSA_KEY = EXAMPLE_SECRET_QUALIFIER + "-----BEGIN PRIVATE KEY-----\n"
130+
+ "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDR0KfxUw7MF/8R\n"
131+
+ "B5/YXOM7yLnoHYb/M/6dyoulMbtEdKKhQhU28o5FiDkHcEG9PJQLgqrRgAjl3VmC\n"
132+
+ "C9omtfZJQ2EpfkTttkJjnKOOroXhYE51/CYSckapBYCVh8GkjUEJuEfnp07cTfYZ\n"
133+
+ "FqViIgIWPZyjkzl3w4girS7kCuzNdDntVJVx5F/EsFwMA8n3C0QazHQoM5s00Fer\n"
134+
+ "6aTwd6AW0JD5QkADavpfzZ554e4HrVGwHlM28WKQQkFzzGu44FFXyVuEF3HeyVPu\n"
135+
+ "g8GRHAc8UU7ijVgJB5TmbvRGYowIErD5i4VvGLuOv9mgR3aVyN0SdJ1N7aJnXpeS\n"
136+
+ "QjAgf03jAgMBAAECggEBAIhQyzwj3WJGWOZkkLqOpufJotcmj/Wwf0VfOdkq9WMl\n"
137+
+ "cB/bAlN/xWVxerPVgDCFch4EWBzi1WUaqbOvJZ2u7QNubmr56aiTmJCFTVI/GyZx\n"
138+
+ "XqiTGN01N6lKtN7xo6LYTyAUhUsBTWAemrx0FSErvTVb9C/mUBj6hbEZ2XQ5kN5t\n"
139+
+ "7qYX4Lu0zyn7s1kX5SLtm5I+YRq7HSwB6wLy+DSroO71izZ/VPwME3SwT5SN+c87\n"
140+
+ "3dkklR7fumNd9dOpSWKrLPnq4aMko00rvIGc63xD1HrEpXUkB5v24YEn7HwCLEH7\n"
141+
+ "b8jrp79j2nCvvR47inpf+BR8FIWAHEOUUqCEzjQkdiECgYEA6ifjMM0f02KPeIs7\n"
142+
+ "zXd1lI7CUmJmzkcklCIpEbKWf/t/PHv3QgqIkJzERzRaJ8b+GhQ4zrSwAhrGUmI8\n"
143+
+ "kDkXIqe2/2ONgIOX2UOHYHyTDQZHnlXyDecvHUTqs2JQZCGBZkXyZ9i0j3BnTymC\n"
144+
+ "iZ8DvEa0nxsbP+U3rgzPQmXiQVMCgYEA5WN2Y/RndbriNsNrsHYRldbPO5nfV9rp\n"
145+
+ "cDzcQU66HRdK5VIdbXT9tlMYCJIZsSqE0tkOwTgEB/sFvF/tIHSCY5iO6hpIyk6g\n"
146+
+ "kkUzPcld4eM0dEPAge7SYUbakB9CMvA7MkDQSXQNFyZ0mH83+UikwT6uYHFh7+ox\n"
147+
+ "N1P+psDhXzECgYEA1gXLVQnIcy/9LxMkgDMWV8j8uMyUZysDthpbK3/uq+A2dhRg\n"
148+
+ "9g4msPd5OBQT65OpIjElk1n4HpRWfWqpLLHiAZ0GWPynk7W0D7P3gyuaRSdeQs0P\n"
149+
+ "x8FtgPVDCN9t13gAjHiWjnC26Py2kNbCKAQeJ/MAmQTvrUFX2VCACJKTcV0CgYAj\n"
150+
+ "xJWSUmrLfb+GQISLOG3Xim434e9keJsLyEGj4U29+YLRLTOvfJ2PD3fg5j8hU/rw\n"
151+
+ "Ea5uTHi8cdTcIa0M8X3fX8txD3YoLYh2JlouGTcNYOst8d6TpBSj3HN6I5Wj8beZ\n"
152+
+ "R2fy/CiKYpGtsbCdq0kdZNO18BgQW9kewncjs1GxEQKBgQCf8q34h6KuHpHSDh9h\n"
153+
+ "YkDTypk0FReWBAVJCzDNDUMhVLFivjcwtaMd2LiC3FMKZYodr52iKg60cj43vbYI\n"
154+
+ "frmFFxoL37rTmUocCTBKc0LhWj6MicI+rcvQYe1uwTrpWdFf1aZJMYRLRczeKtev\n" + "OWaE/9hVZ5+9pild1NukGpOydw==\n"
155+
+ "-----END PRIVATE KEY-----\n";
156+
104157
private final Path tempDir;
105158

106159
public PemFileWriter() throws IOException {

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParserTests.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import org.junit.jupiter.api.BeforeEach;
2929
import org.junit.jupiter.api.Nested;
3030
import org.junit.jupiter.api.Test;
31+
import org.junit.jupiter.params.ParameterizedTest;
32+
import org.junit.jupiter.params.provider.ValueSource;
3133

3234
import org.springframework.boot.buildpack.platform.docker.ssl.PrivateKeyParser.DerEncoder;
3335

@@ -39,6 +41,7 @@
3941
*
4042
* @author Scott Frederick
4143
* @author Phillip Webb
44+
* @author Moritz Halbritter
4245
*/
4346
class PrivateKeyParserTests {
4447

@@ -55,14 +58,34 @@ void tearDown() throws IOException {
5558
}
5659

5760
@Test
58-
void parsePkcs8KeyFile() throws IOException {
59-
Path path = this.fileWriter.writeFile("key.pem", PemFileWriter.CA_PRIVATE_KEY);
61+
void parsePkcs8RsaKeyFile() throws IOException {
62+
Path path = this.fileWriter.writeFile("key.pem", PemFileWriter.PKCS8_PRIVATE_RSA_KEY);
6063
PrivateKey privateKey = PrivateKeyParser.parse(path);
6164
assertThat(privateKey).isNotNull();
6265
assertThat(privateKey.getFormat()).isEqualTo("PKCS#8");
6366
Files.delete(path);
6467
}
6568

69+
@ParameterizedTest
70+
@ValueSource(strings = { PemFileWriter.PKCS8_PRIVATE_EC_NIST_P256_KEY, PemFileWriter.PKCS8_PRIVATE_EC_NIST_P384_KEY,
71+
PemFileWriter.PKCS8_PRIVATE_EC_PRIME256V1_KEY, PemFileWriter.PKCS8_PRIVATE_EC_SECP256R1_KEY })
72+
void parsePkcs8EcKeyFile(String contents) throws IOException {
73+
Path path = this.fileWriter.writeFile("key.pem", contents);
74+
PrivateKey privateKey = PrivateKeyParser.parse(path);
75+
assertThat(privateKey).isNotNull();
76+
assertThat(privateKey.getFormat()).isEqualTo("PKCS#8");
77+
assertThat(privateKey.getAlgorithm()).isEqualTo("EC");
78+
}
79+
80+
@Test
81+
void parsePkcs8DsaKeyFile() throws IOException {
82+
Path path = this.fileWriter.writeFile("key.pem", PemFileWriter.PRIVATE_DSA_KEY);
83+
PrivateKey privateKey = PrivateKeyParser.parse(path);
84+
assertThat(privateKey).isNotNull();
85+
assertThat(privateKey.getFormat()).isEqualTo("PKCS#8");
86+
assertThat(privateKey.getAlgorithm()).isEqualTo("DSA");
87+
}
88+
6689
@Test
6790
void parsePkcs1RsaKeyFile() throws IOException {
6891
Path path = this.fileWriter.writeFile("key.pem", PemFileWriter.PRIVATE_RSA_KEY);

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
import java.security.spec.InvalidKeySpecException;
2828
import java.security.spec.PKCS8EncodedKeySpec;
2929
import java.util.ArrayList;
30-
import java.util.Arrays;
31-
import java.util.Collection;
3230
import java.util.Collections;
3331
import java.util.List;
3432
import java.util.function.Function;
@@ -65,12 +63,9 @@ final class PrivateKeyParser {
6563
private static final List<PemParser> PEM_PARSERS;
6664
static {
6765
List<PemParser> parsers = new ArrayList<>();
68-
parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, Collections.singleton("RSA"),
69-
PrivateKeyParser::createKeySpecForPkcs1));
70-
parsers.add(
71-
new PemParser(EC_HEADER, EC_FOOTER, Collections.singleton("EC"), PrivateKeyParser::createKeySpecForEc));
72-
parsers.add(
73-
new PemParser(PKCS8_HEADER, PKCS8_FOOTER, Arrays.asList("RSA", "EC", "DSA"), PKCS8EncodedKeySpec::new));
66+
parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, PrivateKeyParser::createKeySpecForPkcs1, "RSA"));
67+
parsers.add(new PemParser(EC_HEADER, EC_FOOTER, PrivateKeyParser::createKeySpecForEc, "EC"));
68+
parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, PKCS8EncodedKeySpec::new, "RSA", "EC", "DSA"));
7469
PEM_PARSERS = Collections.unmodifiableList(parsers);
7570
}
7671

@@ -152,12 +147,12 @@ private static class PemParser {
152147

153148
private final Pattern pattern;
154149

155-
private final Collection<String> algorithms;
156-
157150
private final Function<byte[], PKCS8EncodedKeySpec> keySpecFactory;
158151

159-
PemParser(String header, String footer, Collection<String> algorithms,
160-
Function<byte[], PKCS8EncodedKeySpec> keySpecFactory) {
152+
private final String[] algorithms;
153+
154+
PemParser(String header, String footer, Function<byte[], PKCS8EncodedKeySpec> keySpecFactory,
155+
String... algorithms) {
161156
this.pattern = Pattern.compile(header + BASE64_TEXT + footer, Pattern.CASE_INSENSITIVE);
162157
this.algorithms = algorithms;
163158
this.keySpecFactory = keySpecFactory;
@@ -181,7 +176,7 @@ private PrivateKey parse(byte[] bytes) {
181176
try {
182177
return keyFactory.generatePrivate(keySpec);
183178
}
184-
catch (InvalidKeySpecException ignored) {
179+
catch (InvalidKeySpecException ex) {
185180
}
186181
}
187182
return null;

0 commit comments

Comments
 (0)