Como posso usar a autenticação de certificado com HttpsURLConnection?

Estou tentando conectar-me a uma URL HTTPS, mas preciso usar a autenticação do cliente com um certificado colocado no meu sistema por software de terceiro

Eu não tenho a menor idéia de como devo encontrá-lo ou usá-lo e tudo o que tenho para continuar é o código de exemplo C #, que difere significativamente de todas as respostas Java que encontrei sobre isso. (por exemplo, o KeyStore precisa de algum tipo de senha, aparentemente?)

Este é o código de exemplo C # que tenho

System.Security.Cryptography.X509Certificates.X509CertificateCollection SSC_Certs = 
    new System.Security.Cryptography.X509Certificates.X509CertificateCollection();

Microsoft.Web.Services2.Security.X509.X509CertificateStore WS2_store =
    Microsoft.Web.Services2.Security.X509.X509CertificateStore.CurrentUserStore(
    Microsoft.Web.Services2.Security.X509.X509CertificateStore.MyStore);

WS2_store.OpenRead();

Microsoft.Web.Services2.Security.X509.X509CertificateCollection WS2_store_Certs = WS2_store.Certificates;

E então ele itera sobre o WS2_store_Certs CertificateCollection e verifica todos eles dessa maneira. Um pouco mais adiante, ele define os certificados assim:

HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url_string);
httpWebRequest.ClientCertificates = SSC_Certs;

udo isso parece bastante lógico, mesmo que eu não tenha idéia de como encontra os certificados, mas ainda não consegui encontrar o equivalente em Java diss

ATUALIZA

A conexão que estou fazendo faz parte de um aplicativo maior que depende do JDK 5, mas consegui usar o frasco sunmscapi para encontrar o certificado que estou procurando. Erros ao tentar conectar-me usando o keystore do Windows, pensei em solucionar o problema ao obter o certificado necessário na loja do Windows e inseri-lo no java padrão. Agora estou recebendo uma EOFException seguida por uma SSLHandshakeException dizendo "Host remoto fechado de conexão durante o handshake". O rastreamento de depuração do SSL não revela um problema imediato para mim, pois o certificado que eu preciso é exibido na cadeia de certificados aqu

Faz toda a coisa ClientKeyExchange, diz que está concluída e, em seguida, as últimas mensagens que recebo do log de depuração são

[write] MD5 and SHA1 hashes:  len = 16
0000: 14 00 00 0C D3 E1 E7 3D   C2 37 2F 41 F9 38 26 CC  .......=.7/A.8&.
Padded plaintext before ENCRYPTION:  len = 32
0000: 14 00 00 0C D3 E1 E7 3D   C2 37 2F 41 F9 38 26 CC  .......=.7/A.8&.
0010: CB 10 05 A1 3D C3 13 1C   EC 39 ED 93 79 9E 4D B0  ....=....9..y.M.
AWT-EventQueue-1, WRITE: TLSv1 Handshake, length = 32
[Raw write]: length = 37
0000: 16 03 01 00 20 06 B1 D8   8F 9B 70 92 F4 AD 0D 91  .... .....p.....
0010: 25 9C 7D 3E 65 C1 8C A7   F7 DA 09 C0 84 FF F4 4A  %..>e..........J
0020: CE FD 4D 65 8D                                     ..Me.
AWT-EventQueue-1, received EOFException: error

e o código que estou usando para configurar a conexão é

KeyStore jks = KeyStore.getInstance(KeyStore.getDefaultType());
jks.load(null, null);

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
jks.setCertificateEntry("alias", cert1); //X509Certificate obtained from windows keystore
kmf.init(jks, new char[0]);

SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kmf.getKeyManagers(), new TrustManager[]{tm}, null);

sslsocketfactory = sslContext.getSocketFactory();
System.setProperty("https.proxyHost", proxyurl);
System.setProperty("https.proxyPort", proxyport);

Authenticator.setDefault(new MyAuthenticator("proxyID", "proxyPassword"));
URL url = new URL(null, urlStr, new sun.net.www.protocol.https.Handler());
HttpsURLConnection uc = (HttpsURLConnection) url.openConnection();
uc.setSSLSocketFactory(sslsocketfactory);
uc.setAllowUserInteraction(true);
uc.setRequestMethod("POST");
uc.connect();

(Ainda não testei o HttpClient porque não tenho idéia de como encontrar o arquivo de certificado e também não tenho certeza se isso sempre será o mesmo em todos os sistemas clientes.)

ANOTHER UPDATE

Encontrei as CAs para o certificado que preciso no keystore do WINDOWS-ROOT (e verifiquei com .verify () para ver se todos saíam), adicionei-as ao keystore java, mas ainda assim nada muda . Eu acho que eles deveriam ir na TrustStore, mas ainda tenho que encontrar uma maneira de fazer isso programaticamente. (Prefere não confiar nos usuários finais para fazer esse tipo de coisa, pois tudo o que posso garantir é que o certificado e as autoridades de certificação estarão presentes devido ao software de terceiros mencionado no início desta pergunta ridiculamente longa.)

Ainda mais atualizações

Adicionando a atualização anterior, cheguei à conclusão de que meu problema deve estar no fato de minhas CAs não estarem no arquivo cacerts do Java, para que obtenha a lista de CAs confiáveis do servidor, mas não as reconhece. e subsequentemente não envia um único certificado, causando a falha na conexão. Portanto, o problema permanece: como faço para que o Java use seu keystore como armazenamento confiável ou inclua certificados no cacerts programaticamente (sem a necessidade de caminhos de arquivo)? Porque se isso não for possível, isso me deixa com a opção secreta C, voodoo. Vou começar a esfaquear uma boneca Duke com agulhas, só por precauçã

questionAnswers(3)

yourAnswerToTheQuestion