Я пытаюсь использовать API стороннего сервера. Третья сторона прислала мне сертификат SSL.p12 с сертификатом, который является файлом сертификата, который я использую для рукопожатия. Я создал пользовательский RestTemplate с SSL следующим образом:
@Configuration
public class CustomRestTemplate {
private static final String PASSWORD = "fake_password";
private static final String RESOURCE_PATH = "keystore/certificate.p12";
private static final String KEY_TYPE = "PKCS12";
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) throws Exception {
char[] password = PASSWORD.toCharArray();
SSLContext sslContext = SSLContextBuilder
.create()
// .loadKeyMaterial(keyStore(RESOURCE_PATH, password), password)
.loadKeyMaterial(keyStore(getClass().getClassLoader().getResource(RESOURCE_PATH).getFile(), password), password)
.loadTrustMaterial(null, new TrustSelfSignedStrategy())
.build();
HttpClient client = HttpClients
.custom()
.setSSLContext(sslContext)
.build();
return builder
.requestFactory(() -> new HttpComponentsClientHttpRequestFactory(client))
.build();
}
private KeyStore keyStore(String file, char[] password) throws Exception {
KeyStore keyStore = KeyStore.getInstance(KEY_TYPE);
File key = ResourceUtils.getFile(file);
try (InputStream in = new FileInputStream(key)) {
keyStore.load(in, password);
}
return keyStore;
}
}
Затем я вызываю конечную точку, используя следующий код:
@Component
@Service
public class TransactionService implements TransactionInterface {
@Autowired
private CustomRestTemplate restTemplate = new CustomRestTemplate();
private static final String BASE_URL = "https://41.x.x.x:xxxx/";
@Override
public List<Transaction> getUnsentTransactions(int connectionId) throws Exception {
HttpEntity<?> httpEntity = new HttpEntity<>(null, new HttpHeaders());
ResponseEntity<Transaction[]> resp = restTemplate
.restTemplate(new RestTemplateBuilder())
.exchange(BASE_URL + "path/end_point/" + connectionId, HttpMethod.GET, httpEntity, Transaction[].class);
return Arrays.asList(resp.getBody());
}
}
Я получаю следующую трассировку стека при попытке использовать API:
org.springframework.web.client.ResourceAccessException: I/O error on GET request for \"https://41.x.x.x:xxxx/path/endpoint/parameters\": Certificate for <41.x.x.x> doesn't match any of the subject alternative names: [some_name_here, some_name_here];
У меня нет большого опыта работы с TLS или SSL-сертификатами. Я действительно застрял в данный момент и надеюсь, что смогу получить некоторую помощь здесь. Сторонний разработчик предоставил мне сайт для тестирования, где я могу проверить конечные точки, и после импорта файла certificate.p12 в мой браузер я могу достичь конечных точек с помощью их сайта тестирования, но мое приложение Springboot все еще не достигает конечной точки.
Нужно ли копировать сертификат в определенную папку? Это не похоже на случай, потому что я получаю исключение FileNotFoundException, если я изменяю путь или имя файла и получаю неверную ошибку пароля, если я ввожу неправильный пароль для файла certificate.p12. Я попытался использовать Postman для тестирования, но Postman возвращает ту же самую трассировку стека, что и мое веб-приложение.
Глядя на информацию выше, я что-то упустил? Склад ключей не создается во время выполнения? Нужно ли привязывать сертификат к JVM или моему исходящему запросу?
Любая помощь будет оценена.
Спасибо