首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Springboot SLL消费

Springboot SLL消费
EN

Stack Overflow用户
提问于 2019-04-01 10:44:36
回答 1查看 578关注 0票数 0

我正在尝试使用第三方服务器的API。第三方给我发了一个名为certificate.p12的SSL证书,这是我用来进行握手的证书文件。我已经使用SSL创建了一个自定义RestTemplate,如下所示:

代码语言:javascript
复制
@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;
    }
}

然后使用以下代码调用端点:

代码语言:javascript
复制
@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时,我得到了以下堆栈跟踪:

代码语言:javascript
复制
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返回与我的web应用程序相同的堆栈跟踪。

看看上面的信息,我是不是漏掉了什么?密钥库不是在运行时创建的吗?是否需要将证书绑定到JVM或传出请求?

任何帮助都将不胜感激。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-01 11:43:31

看起来,您正在尝试连接到证书中没有有效名称的服务器。例如,如果连接到"stackoverflow.com",证书需要"subject“或"subject alternative names”字段中的域。

即使是一个测试站点也应该有一个有效的证书,但是如果这是不可能的(因为它是第三方站点,而且您自己也不能更改它),您可以使用this question禁用验证

当然,这只能用于测试。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55453261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档