I would like to generate an SSH keypair for the client on the server.
My previous design was to use rest API to send the post request(or should I use get?) to the backend, then generate the keypair and return it to frontend. Then create the URL for the private key file with the download.
But seems it might cause some safety issue in this way. I'm not familiar with security, so I actually don't know what security problem might cause, and where it would happen.
I hope I can get some idea for the solution, and any suggestions or explain would be helpful.
Thank you!
You can't do it unless ...
you already have a secure channel over which to send the private key, or
the client and server already have a shared key or keypair that can be used to create such a channel.
But the good news is that if your server implements HTTPS (or a similar SSL based protocol) and has a proper SSL certificate with a proper root CA, then a channel created by a client to the HTTPS endpoint should be secure. All you then need is a way for the server to authenticate the client; e.g. an account name + password or a client certificate. (But that implies a shared secret ... for authenticating the client to the server.)
Generally speaking, solutions to this involve some kind of bootstrapping, starting with a shared secret that is injected "out of band"; e.g. in a boot image, or first-boot injection or a USB stick.
Note that this kind of thing should really be set up by someone who understands security, 'cos the damage caused if you get it wrong could be incalculable.
So ...
I would like to generate an SSH keypair for the client on the server.
The simple answer is don't do it that way around. Implement it the other way around. Generate the keypair on the client side and send the public key to the server.
Related
I am trying to build a client / server servlet application with these general requisites:
both the client and the server are jetty embedded;
the server expose a servlet in order to receive json data via POST;
the connection must be secured via SSL (i.e. the connection will be done via Internet via https);
I want that only my Jetty client be able to send data to my server, all other tentative must be refused by the server;
the server and the client are unattended machines (i.e. not password via command line could be inserted by human);
no password in clear must be stored on the client device. In general I don't want someone could open the remote client device and stole the password and building a fake remote device capable to send data to my server too.
I have build a perfectly working client / server application via HTTP but I am confused about the security.
I have read that there is the possibility to use client / server mutual authentication and seems what I am looking for but I can't get the complete picture.
In this document client-certificate-authentication there is a more or less clear explanation about how to build a shared trusted CA but the password for accessing the TrustStore and the KeyStore are in clear in the code.
I think I am missing a tile in the puzzle.
Could someone point me in the right direction?
Thanks,
S.
I'm going with a simple answer (for now).
If you just want only your clients to talk to the server, then yes, Client SSL/TLS certificates are the way to go.
You'll want the server's SslContextFactory.Server.setNeedClientAuth(true) set to true. That will in turn cause Java's javax.net.ssl.SSLParameters.setNeedClientAuth(true) to be set on incoming connection establishment. If the client fails to provide the client certificate, the connection is closed, and no HTTP request is sent or processed.
As for securing the client certificate, that's up to you, you can do anything you want to do, as long as it results in a valid client SslContextFactory.Client that the Jetty client can access. This includes ...
Using plaintext passwords
Using obfuscated passwords (minimal effort, minimal security)
Encrypted keystore/truststore passwords elsewhere in your client, provided to the SslContextFactory.Client at the last minute. (modest security, wouldn't be that hard to figure out)
Creating the java.security.KeyStore object yourself and handing it to SslContextFactory.Client.setKeyStore(KeyStore) and SslContextFactory.Client.setTrustStore(KeyStore) methods prior to starting the Jetty Client. (a bit better security wise, puts more work on your behalf)
You might want to consider having the client certificates be short-lived (24 hours?) dynamically refreshed from the server, and have the client certificates be revokable (at the server/CA side) if you encounter abuse. (such as the same client certificate from multiple different client IPs)
I have a java client which communicates with python server. Both run within out company intranet. None are exposed to Internet. How I am supposed to ensure that communication happens over SSL?
I have read a lot online and I have come up with following conclusions:
I will generate primary key and certificate to be used by clients and server using java keytool. (creating keystore, private key, certificate and truststore,extracting private key from keystore)
Using private key and certificate inside my python server using SSLSocket class as explained here
Using certificate in truststore inside java client as explained here
I have some doubts:
Are above steps ok?
Above seems to be one way SSL. Should I be doing two way SSL?
Should I be creating shared secret key and communicating using it?
I know this is something related to requirements. But I am in doubt as I am doing SSL first time.
SSL certificates requires validation via (HTTP/HTTPS), I suggest you enable HTTP/HTTPS for the location IP on the router/firewall to allow the validation to go through the internet.
If that is not possible, then you might have to do some local-server SSL validation. By generating a "SELF SIGNED" certificate and registering it manually in both locations.
I am working on a chat application, made in Java for android. I have a server created in python, using twisted, and of course, in my android app I have the client implemented.
It's working very well, but I want to make it secure. I was looking at RSA encryption and found this link: http://javadigest.wordpress.com/2012/08/26/rsa-encryption-example/
The problem is that, I can make a pair of keys, a private key that will be on the server to decrypt the messages and the public key will hard-coded (or somewhere online), in the android application. The problem would be, when the server sends the message back to the client, how will he be able to get it ? That one needs to be send encrypted as well, otherwise, there's no point in doing it. I was thinking about creating a pair of keys for each client, but ... I think it's not the best approach.
All suggestions are welcome
The solution to this is usually to create a form of Public Key Infrastructure (PKI), where the public keys of the clients can be verified when needed. You can do this by putting them into a certificate and sign it by some kind of certificate authority (CA) that you control. That way you don't need to store all the certificates, and you can also revoke certificates of clients that have their key compromised. This is what is normally used by (browser) TLS, especially if client authentication is deployed.
Key management however is a large topic that cannot be handled within one answer.
I'm trying to improve some code that enables logging in to our application using digital certificates, probably certificates stored on PKCS11 tokens.
It's a Java client server application, with the server on JBoss [Wildfly], and a rich Java thick client. We also have a GWT/Javascript based web client, but this doesn't yet support certificate auth.
The current implementation uses 2-way SSL authentication if certificate authentication is configured, i.e. the server will require a client certificate when the connection is opened. This causes some problems, and in trying to find ways to address them I've been searching madly to see if there is a standard, 'Right Way To Do PKI Auth To A JBoss Application'.
However just about everything I have found on the subject seems also to revolve around using two-way SSL, which kind of implies that is the Right Way to Do It.
It seems undesirable to me, in that the network transport is quite a low-level concern, heavily separated from the application logic and stuff like authentication and user management.
In order to prove the client is a valid user of the system (as opposed to merely someone with credentials endorsed by a CA in the server trust store), the server application logic has to rummage around looking to find the certificate that was used on the incoming connection in order to scrape the Common Name off it. I've discovered that javax.servlet.request.X509Certificate is a standard-ish parameter one can query on the servlet, so it ought at least to be possible.
The other architectural problem this causes is that our app requires reauthentication for the lifetime of certain sensitive operations. If one is using the SSL connection to prove the user has the private key, then logically that would require opening a whole separate connection.
Logically, authenticating with a certificate would seem to require
The server generating a nonce
The client encrypting the nonce using the client's private key
The client sending that encrypted value to the server with the accompanying public certificate [or certificate chain].
Now, that is exactly what happens during an SSL handshake, but obviously a whole load of other baggage comes with it that is irrelevant to the application-level concern of authenticating the user.
I thought about implementing the steps directly myself, but this would seem to violate the first rule of crypto (Don't implement your own crypto).
If the server generates random nonces then that introduces a level of chattiness and statefulness to the process, which is doable but a pain when you are striving for a stateless and clusterable server.
Time-based One-Time Password implementations circumvent this, and seem to be a standardized mechanism for 2-factor authentication that is getting support from Google+ and the like.
However I can't find anything in the way of out-of-the-box libraries that will let me build an implementation using certificates directly from an imposed PKI.
I'm working on a server-to-server authentication via RMI. There's on application-server (server part) and several web-servers (client part) which communicate via RMI. The web-server(s) must authenticate on the application-server. The simplest way would be to use a password which is stored in the web-server's config-file (clear text), but that's obviously very bad practice.
My idea is to use a public/private-key which is generated on the web-server (client). The privateKey is stored in keystore and the publicKey is published to the app-server. To authenticate the client, a generated, random String is signed with the privateKey (create a Signature) and both, the signature und the String are send to the server. The server verifies the String with the signature and it's publicKey. Good idea?
I know this is not very secure but even better than storing clear text password.
Any suggestions for that?
There's no need to make it 100% secure, just a good alternative for password protection.
Thanks and have a nice day.
Public /private key encryption should be good enough.
Other alternatives would be to store the password in an LDAP server and give access to both the server as well as the clients to the LDAP. However, this would add a burden of one more server and some more network usage.
The ultimate security will be to use Secure RMI, this will protect your RMI messages as well as protect the connections to the server.