【问题标题】:Jersey Client with SSL Mutual Authentication具有 SSL 相互身份验证的 Jersey 客户端
【发布时间】:2019-04-03 14:08:35
【问题描述】:

我有一个用 java 编写的代码,我使用 jersey 客户端,我尝试进行相互认证,所以我也有一个 .jks,其中包含我由 CA 签署的证书,所以这是我的代码

@SuppressWarnings("static-access")
@POST
@Path("PruebaPlumaCalva")
public Response testPlumaCalva(String jsonObject)
{
    // ClientBuilder.newClient().
    logger.debug("Test");
    Map<String, Object> payload = new HashMap<String, Object>();
    payload.put("documentType", x);
    payload.put("documentNumber", xxxxxx);
    payload.put("partner", "xxx");
    payload.put("transactionId", "xxxxx");

    logger.debug("Mis parametros son:" + payload);
    String json = null;

    try
    {
        json = (new ObjectMapper()).writeValueAsString(payload);
    }
    catch (JsonProcessingException e)
    {
    }

    HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("xxxxx", "xxxx");
    //SSLContext scl = SslConfigurator.newInstance().trustStoreFile("C:/Users/juan.rojas/Documents/Juan José/Proyectos/PagosMoviles/KeyStore.jks").trustStorePassword("123456").keyStoreFile("C:/Users/juan.rojas/Documents/Juan José/Proyectos/PagosMoviles/KeyStore.jks").keyPassword("123456").createSSLContext();
    SSLContext scl = SslConfigurator.newInstance().trustStoreFile("/cdrive/f_drive/Pos.jks").trustStorePassword("123456").keyStoreFile("/cdrive/f_drive/Pos.jks").keyPassword("test").createSSLContext();
    Client client = ClientBuilder.newBuilder()
            .sslContext(scl)
            .build();
    client.register(feature);
    WebTarget webTarget = client.target("xxxxxxxx");
    Invocation.Builder invocationB = webTarget.request(MediaType.APPLICATION_JSON_TYPE);
    Response response = invocationB.post(Entity.json(json));
    JsonNode jsonNode = bonusUtilities.createJsonNode(response);
    logger.debug("JsonNode Answer" + jsonNode);
    int x = 0;

    return response;
}

因此,当我仅使用 1 个证书执行该代码时,他运行良好,但是当我有 2 个证书时,他无法运行,我认为问题在于 .jks 不知道他必须使用哪个证书,但我不知道如何要指定他必须使用哪一个,我已经看了很多论坛,但我看不到有人为我提供了解决问题的方法

【问题讨论】:

    标签: java ssl jersey keytool jersey-client


    【解决方案1】:

    我遇到了同样的问题,感谢answer,我可以解决它。 基本上,没有办法做到这一点“开箱即用”,您必须实现自己的 KeyManager。

    我进一步简化了链接的答案,代码如下所示:

    public class FilteredKeyManager implements X509KeyManager {
    
        private final X509KeyManager originatingKeyManager;
    
        public FilteredKeyManager(X509KeyManager originatingKeyManager) {
            this.originatingKeyManager = originatingKeyManager;
        }
    
        @Override
        public String chooseClientAlias(String[] arg0, Principal[] arg1, Socket arg2) {
            return "yourAliasHere";
        }
    }
    

    对于其余被覆盖的方法,只需调用 originatingKeyManager。

    为了创建 SSLContext,我没有使用 SSLConfigurator,但参数是相同的(路径和密码)。

    // Init keystore
    KeyStore ks = KeyStore.getInstance("JKS");
    FileInputStream ksFile = new FileInputStream("yourKeystorePath");
    ks.load(ksFile, "keystorePassword".toCharArray());
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(ks, pass);
    
    // Init truststore
    KeyStore trustKeystore = KeyStore.getInstance("JKS"));
    FileInputStream tsFile = new FileInputStream("yourTruststorePath"));
    trustKeystore.load(tsFile, "truststorePassword".toCharArray());
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(trustKeystore);
    
    // Create instance of custom KeyManager
    KeyManager[] km = new KeyManager[] { new FilteredKeyManager((X509KeyManager) kmf.getKeyManagers()[0]) };
    
    // Create SSLContext using custom KeyManager
    SSLContext context = SSLContext.getInstance("TLSv1");
    context.init(km, ts, new SecureRandom());
    

    【讨论】:

      猜你喜欢
      • 2014-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 2014-09-15
      • 2014-11-13
      相关资源
      最近更新 更多