我需要使用Spring调用一个带有SSL双向(X509)的API REST。我的JKS文件得到多别名(强制性)。
我从以下代码开始创建一个rest模板:
KeyStore clientTrustStore = getStore(trustStore, pwdTrustStore.toCharArray());
KeyStore clientKeyStore = getStore(keyStore, pwdKeyStore.toCharArray());
SSLContext sslContext = new SSLContextBuilder()
.setKeyStoreType(JAVA_KEYSTORE)
//.setKeyManagerFactoryAlgorithm(...)
.loadKeyMaterial(clientKeyStore, aliasPwd.toCharArray(), new KeyStrategy(alias))
.loadTrustMaterial(clientTrustStore, new TrustSelfSignedStrategy())
.build();
SSLConnectionSocketFactory sslConFactory = new SSLConnectionSocketFactory(sslContext);
try (CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConFactory).build()) {
restTemplateBuilder.requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient));
}
this.restTemplate = restTemplateBuilder.build();
字符串
对于那些知道它是如何工作的人来说,它使用SunX509KeyManagerImpl.class(JDK 8)来使用该算法解析密钥库
SunX509KeyManagerImpl(KeyStore ks, char[] password)
throws KeyStoreException,
NoSuchAlgorithmException, UnrecoverableKeyException {
credentialsMap = new HashMap<String,X509Credentials>();
serverAliasCache = Collections.synchronizedMap(
new HashMap<String,String[]>());
if (ks == null) {
return;
}
for (Enumeration<String> aliases = ks.aliases();
aliases.hasMoreElements(); ) {
String alias = aliases.nextElement();
if (!ks.isKeyEntry(alias)) {
continue;
}
Key key = ks.getKey(alias, password);
if (key instanceof PrivateKey == false) {
continue;
}
Certificate[] certs = ks.getCertificateChain(alias);
if ((certs == null) || (certs.length == 0) ||
!(certs[0] instanceof X509Certificate)) {
continue;
}
if (!(certs instanceof X509Certificate[])) {
Certificate[] tmp = new X509Certificate[certs.length];
System.arraycopy(certs, 0, tmp, 0, certs.length);
certs = tmp;
}
X509Credentials cred = new X509Credentials((PrivateKey)key,
(X509Certificate[])certs);
credentialsMap.put(alias, cred);
if (SSLLogger.isOn && SSLLogger.isOn("keymanager")) {
SSLLogger.fine("found key for : " + alias, (Object[])certs);
}
}
}
型
正如您在for旁边看到的,它使用枚举提取别名列表,并使用密码和列表的第一个随机别名执行getKey。当duo别名/pwd错误时,它会抛出异常java.security.UnrecoverableKeyException: Cannot recover key
我不明白为什么我不能过滤将要测试的别名,或者所有的别名必须有相同的密码?:).我看到我可以使用setKeyManagerFactoryAlgorithm来创建一个自定义的KeyManager(不使用de SunX 509 KeyManagerImpl),但我想知道它是否是真实的的好解决方案,以达到我的目标.
我不想重新发明轮子
谢谢你的回复
1条答案
按热度按时间vh0rcniy1#
看起来我可以从密钥存储库中提取密钥,并在内存中创建只有一个别名的密钥存储库。
字符串
所以我将用它来调用我的REST API