Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set SSL Client Certificate #684

Closed
alexvrv opened this issue Dec 7, 2023 · 24 comments
Closed

Set SSL Client Certificate #684

alexvrv opened this issue Dec 7, 2023 · 24 comments
Assignees

Comments

@alexvrv
Copy link

alexvrv commented Dec 7, 2023

Hi, is there a way to set a specific Certificate (X509Certificate) for a SSL connection? I see options to set one but it requires a InputStream which I don't have. In the KeyStore I have 3 certificates and I need to be able to use a specific one. Or maybe a SSLContext like JSOUP uses

SSLContext sc = SSLContext.getInstance("TLS"); sc.init(new X509ExtendedKeyManager[] {km}, null, null); Jsoup.connect(URL).sslSocketFactory(sc.getSocketFactory()).ignoreContentType(true).execute();

@rbri
Copy link
Member

rbri commented Dec 7, 2023

there was a similar thing - maybe you can have a look at #623

@rbri
Copy link
Member

rbri commented Dec 7, 2023

for filtering out you can have a look at the comment of method setSSLClientCertificate

@alexvrv
Copy link
Author

alexvrv commented Dec 7, 2023

Yeah I know. The problem is that if I load the entire KeyStore, it chooses the first Certificate in that KeyStore ... if I have multiple Certificates well I can't choose a specific one (they are all valid and usable). I have multiple certificates that I use for different websites, and of course they are on a USB stick so I can't store them and build another KeyStore.

@rbri
Copy link
Member

rbri commented Dec 7, 2023

but you can wrap the key store and provide only the one required

@rbri
Copy link
Member

rbri commented Dec 7, 2023

but i will have a look again, maybe we can provide a more convenient way to do that, or maybe we can have a default impl for that use case

@alexvrv
Copy link
Author

alexvrv commented Dec 7, 2023

What do you mean by wrapping the KeyStore? I don't really get that, sorry

@rbri
Copy link
Member

rbri commented Dec 7, 2023

Implement a keystore, that forwards most of the methods to the containing keystore but filters the certificates.
See the wrapper pattern....

@rbri rbri self-assigned this Dec 7, 2023
@alexvrv
Copy link
Author

alexvrv commented Dec 7, 2023

X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
InputStream is = new ByteArrayInputStream(cert.getEncoded());
webClient.getOptions().setSSLClientCertificate(is, "", "");

Not even this works because in the setSSLClientCertificate you retrieve the entire KeyStore again.

@rbri
Copy link
Member

rbri commented Dec 9, 2023

@alexvrv

  1. you are (more or less :-)) right - i think the naming of the method is confusing (e.g. setSSLClientCertificate should be named setSSLClientCertificateKeyStore)
  2. i like to change this a bit and provide more documentation

Can we do this together - i will update the impl and the documentation and you do the review and testing?

@rbri
Copy link
Member

rbri commented Dec 9, 2023

@alexvrv ok my hint with the wrapped keystore was totally wrong - there is no way to implement such a wrapper.

Instead you can create a new (in memory) KeyStore and add only the certificates you like to use.

see https://www.baeldung.com/java-keystore for some hints how to do this

Then you set this KeyStore using WebClientOptions.setSSLClientCertificateKeyStore(KeyStore, char[])

Does this work for you?

@alexvrv
Copy link
Author

alexvrv commented Dec 11, 2023

@alexvrv

  1. you are (more or less :-)) right - i think the naming of the method is confusing (e.g. setSSLClientCertificate should be named setSSLClientCertificateKeyStore)
  2. i like to change this a bit and provide more documentation

Can we do this together - i will update the impl and the documentation and you do the review and testing?

Sure!

@alexvrv
Copy link
Author

alexvrv commented Dec 11, 2023

@alexvrv ok my hint with the wrapped keystore was totally wrong - there is no way to implement such a wrapper.

Instead you can create a new (in memory) KeyStore and add only the certificates you like to use.

see https://www.baeldung.com/java-keystore for some hints how to do this

Then you set this KeyStore using WebClientOptions.setSSLClientCertificateKeyStore(KeyStore, char[])

Does this work for you?

I've tried this but it works only with PKCS12. I have PKCS11 (certificates on a USB memory stick) which cannot be stored... I can't save the private key and move it into a "in memory" keystore :(
If I try to store the keystore it generates and empty file and from what I've read, this is the behavior of PKCS11 because the private key is stored only on the USB...

@rbri
Copy link
Member

rbri commented Dec 11, 2023

@alexvrv maybe is still on the wrong path:

My current understanding is

  • you have an usb stick holding some (3) PKCS11certificates - but in one 'file'
  • you are able to read the certificates together into one (java) key store
    • there is no way to read only one certificate
  • you like to provide only one certificate to HtmlUnit - not the whole key store with all three

Correct?

@rbri
Copy link
Member

rbri commented Dec 11, 2023

and the solution from #623 does not work - reading all three and then remove the not used ones?

@alexvrv
Copy link
Author

alexvrv commented Dec 12, 2023

@alexvrv maybe is still on the wrong path:

My current understanding is

  • you have an usb stick holding some (3) PKCS11certificates - but in one 'file'

  • you are able to read the certificates together into one (java) key store

    • there is no way to read only one certificate
  • you like to provide only one certificate to HtmlUnit - not the whole key store with all three

Correct?

I have 3 USB sticks, each having their own certificate. The rest is correct.

@alexvrv
Copy link
Author

alexvrv commented Dec 12, 2023

and the solution from #623 does not work - reading all three and then remove the not used ones?

This method kind of works. I can delete the not used certificates, but they get deleted for good. If I want to use another certificate (that I've deleted earlier) I need to reinstall it xD

@alexvrv
Copy link
Author

alexvrv commented Jan 22, 2024

Any news about this? :(

@rbri
Copy link
Member

rbri commented Sep 23, 2024

made a new snapshot build - @alexvrv please have a look at the impl and please try

@alexvrv
Copy link
Author

alexvrv commented Sep 24, 2024

Snapshot 4.5.0 isn't working as intended in my PR ....

@rbri
Copy link
Member

rbri commented Sep 24, 2024

Some more details please

@alexvrv
Copy link
Author

alexvrv commented Sep 24, 2024

I don't have much more details other than the, using the SNAPSHOT it doesn't set the SSLContext that i'm providing ... works perfectly with my changes that I've submitted in the PR

EDIT: i had the setUseInsecureSSL(true), without it works. So I guess it was my bad.

@rbri
Copy link
Member

rbri commented Sep 24, 2024

there was also a stupid error in my code - snapshot is updated

@alexvrv
Copy link
Author

alexvrv commented Sep 24, 2024

I've just refreshed the dependencies and tested. Works perfectly! Thank you!

@rbri
Copy link
Member

rbri commented Sep 24, 2024

Ok, great will close this. Many thanks for your contribution.

@rbri rbri closed this as completed Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants