kaikramer / keystore-explorer

KeyStore Explorer is a free GUI replacement for the Java command-line utilities keytool and jarsigner.
https://keystore-explorer.org/
GNU General Public License v3.0
1.61k stars 265 forks source link

Password Manager for keystore files #51

Open tdpoa2j opened 7 years ago

tdpoa2j commented 7 years ago

I manage hundreds of keystore files for web servers and keeping track of the storepass passwords is my biggest challenge. Please add a password manager where I can enter in a master password at startup that gives me access to all storepass passwords. The storepass assigned to each keystore must be viewable (if in the master password list). When I open a keystore that is the password manager, the storepass is used automatically

When I create a new keystore, automatically generate a complex random storepass and store in the password manager.

kaikramer commented 7 years ago

I like that suggestion, but the feature set for the next release (5.3) is already complete. Maybe in the release after that.

If somebody wants to contribute this feature, please feel free to do so.

As far as I know CERTivity has a built-in password manager, but you have to pay for it.

Colbix commented 1 year ago

@kaikramer I may have a suggestion for implementing this feature. Having the OS handle the storage of the passwords would work and should shift involvement with properly encrypting and storage to the OS.

I've examined a Microsoft project for authentication in java[^1]. As it's not been updated in at least 2 years it's fallen a behind on upkeep. I've been able to get the Microsoft Credential Manager to work. Linux will require some work as there was a migration for how a credentials are stored, to libsecrets, however I found a replacement[^2]. I don't have a MacOS environment to test so the MS project may or may not work.

Here is a code snippet I used to store and retrieve an MS Credential from the manager.

  final SecretStore<Credential> credStore = StorageProvider.getCredentialStorage(true, SecureOption.PREFER);
  //Add to MS Credential Manager
  String sName = "TestSubject01";
  String sPass = "thiswasatriumph";
  String sAddress = "GlaDOS";
  Credential cred = new Credential(sName, sPass);
  credStore.add(sAddress, cred);
  System.out.println(credStore.get(sAddress).Username + " : " + credStore.get(sAddress).Password);

Edit: I've done some additional digging and testing it looks like the original MS vsts project still works on Linux. I am able to save and retrieve a credential and password. There is a problem with the gnome-keyring-daemon where passwords aren't displayed through Seahorse, see reference^3, however programmatically I am able to still use the system. Ideally I'd like verification through Seahorse but for now the code appears to function.

References: [^1]: vsts authentication library for java [^2]: Secret Service

kaikramer commented 1 year ago

@Colbix Thanks for your suggestion. I will take a look at it. A password manager seems like a nice addition to KSE. Even if the project is not supported anymore, it could be forked and bugs like the one with Seahorse.

Colbix commented 1 year ago

After downloading the repo, and importing into the IDE, I performed the following steps for environmental setup:

1) Apply PR 37 from the project[^1] 2) Export common, core, providers, and storage as JARs. 3) To import to KSE add external JARs, to include the recently exported JARs, as well as the following:

References: [^1]: PR 37

SubOptimal commented 1 year ago

Wouldn't be a solution based on a Java KeyStore more platform independent? And it could be managed by KSE.

Colbix commented 1 year ago

I don't see why both could not be offered. The options for password management would be off, keystore, and OS storage.

SubOptimal commented 1 year ago

You would need

Whereas an implementation based on a Java KeyStore could be even portable between different systems.

Colbix commented 1 year ago

The MS authentication project already has that capability for each OS. I would encourage you to read through it to have a better understanding of what it offers. It doesn't have to be an either/or decision. Besides to make this a robust feature there should be other options to choose from.

kaikramer commented 1 year ago

Both solutions have advantages and disadvantages.

Keystore: (+) One implementation that always works (+) No further dependencies (-) Has only the alias name as a way to store metadata together with the password (like the name and path to the keystore that belongs to the password) (-) Requires to enter its password before it can be used

OS password management via "VS Team Services Authentication Library": (+) Accessing the stored passwords should be possible without entering a password (at least on Windows) (+) Uses existing OS mechanisms for password storage (-) Library seems unmaintained (last commit was 4 years ago) (-) Library has no documentation apart from one example application (please correct me if I am wrong here) (-) Library adds additional dependencies to KSE like Jackson and SLF4j

Therefore I am open for both solutions.

We will definitely have to take a closer look at the MS library and answer the following questions:

Colbix commented 1 year ago

This may be a good opportunity to make use of Service Provider Interface (SPI)^1. Using an SPI will allow for extensibility and compartmentalization with other password managers.

Colbix commented 1 year ago

We will definitely have to take a closer look at the MS library and answer the following questions:

Agreed.

KSE uses JNA 5.9 right now, the MS library JNA 4.2.1: Is an upgrade to 5.9 possible?

I added JNA 5.12.1 and Platform 5.12.1 to test and it worked. Additionally I used Platform 4.2.1 with KSE's JNA 5.9 which also worked.

How well does it work right now on the other two operating systems?

Testing with Windows and Linux worked with their respective credential stores.

Is it feasible to maintain this library alongside KSE? Do we understand the source code and can fix bugs if necessary?

That's a good question. I understand parts of it and how it interacts with their respective stores but I'm not an expert by any means. I believe this provides a good starting point. Also if an SPI is used it will allow for separate managers as they are added so KSE is not stuck with something that is broken.

Can we slim down the code to those features that are required for usage in KSE, so that maintenance becomes easier?

I've forked the MS project and created a separate branch for additional testing[^1]. After reviewing the libraries Common and Storage were all that's needed. The other libraries are focused on Azure PAT and oAuth tokens so not useful for this project that I can reason. All references to logging have been removed and PR 37 was applied. The other libraries I suspect are Maven artifacts and not required based on the imports. I can probably further strip more from the Common and Storage libraries later but for now I'll leave it mostly intact sans logging.

Importing external JARs Common, Storage, JNA 5.12.1, and JNA-platform-5.12.1, I was able to confirm the code snippet still worked without any issue on Windows and Linux.

[^1]: New Branch

kaikramer commented 1 year ago

Nice work!

SubOptimal commented 1 year ago

The MS authentication project already has that capability for each OS. I would encourage you to read through it to have a better understanding of what it offers. It doesn't have to be an either/or decision. Besides to make this a robust feature there should be other options to choose from.

On Linux side it does support the Gnome keyring only, at least that's what mentioned in the documentation user-content-available-secure-storage-providers. If this is the case it would not work (well) for non Gnome based desktops.

Using SPI would be interesting, as it even would allow other storage providers.

kaikramer commented 1 year ago

To be honest I am not fully convinced that SPI brings much of an advantage here. If we want to add or replace a password manager we can simply do it, same for additional storage options. Keep in mind that there might be additional UI elements necessary in KSE to allow certain implementations and if code changes are necessary anyway, then we can also just add direct support for this implementation. SPI would mostly be useful if we cannot add a library to the KSE distribution package because of license incompatibilities. On the other hand there is not really a reason to not use SPI here...

weberjn commented 6 months ago

Why not just automatically try changeit and only prompt for a password if it fails? This would already save a lot of typing, at least in development. And add an option to save your most used three or five passwords to try automatically. People don't bother to use another password as it is behind -Djavax.net.ssl.keyStorePassword in server start scripts anyway.

kaikramer commented 6 months ago

Why not just automatically try changeit and only prompt for a password if it fails?

That is what KSE already does for the cacerts truststore (File > Open Special -> Open CA Certificates), where "changeit" is the default password.

We obviously could do the same for any keystore file and it might work in some cases, but in my experience "changeit" is not the most obvious choice for a keystore password for most people. If the keystore is used only for testing purposes something easier might be preferrable (like "123" or "passwd"). If the keystore is used for something more serious, then "changeit" seems like a very weak choice. There are ways to protect the password on the server, it does not necessarily have to be in plaintext behind -Djavax.net.ssl.keyStorePassword. Apart from that, storage of TLS keys/certificates is not the only use case for keystores.

But we might still do this little magic thing and automatically try some of the most common weak passwords. It is not much effort to implement and certainly improves the user experience when it works.

And add an option to save your most used three or five passwords to try automatically.

Here we are exactly at the problem again that has been discussed extensively in this thread: How to save the passwords in a reasonably secure way? If we have a solution for this problem, then a real keystore password manager functionality is not far away anymore.

I think the two options that have been examined so far (either use the OS specific password store or put the passwords in a keystore) are both not suitable for KSE. What we should do instead:

weberjn commented 6 months ago

Production passwords are kept in Keepass or gopass, of course.

But in dev the password is simple and could be stored in keystore-explorer.

If you like it more secure in dev and store passwords in Keepass, keystore-explorer could use one of the Keepass plugins like Kee or KeePassRPC.

it does not necessarily have to be in plaintext behind -Djavax.net.ssl.keyStorePassword.

Yes, you can hide it with a password buried in the server code. But the only really secure way is to type in the password on the console each time the server starts. And hope that there is no key logger. But if you are sure the Unix security is not compromised, you can rely on Unix security and leave your passwords in plain text anyway, at least until the disk appears on ebay.

kaikramer commented 6 months ago

Production passwords are kept in Keepass or gopass, of course.

Keepass does exactly what I have described above as the plan for KSE's password manager, just with Argon2 instead of PBKDF2. But there are much more secure options for storing production passwords.

But in dev the password is simple and could be stored in keystore-explorer.

DEV and PROD are the two extremes, but there is a lot of space in between for environments that don't have to be as secure as PROD, but more than DEV.

If you like it more secure in dev and store passwords in Keepass, keystore-explorer could use one of the Keepass plugins like Kee or KeePassRPC.

The problems with that solution are:

  1. The user of KSE has also to use KeePass. Even on Windows this is quite a stretch. On other platforms where only a more or less good port of KeePass is available, this seems rather bold. On macOS for example 1Password is very popular.
  2. Implementation effort would be similar to a KSE-only solution. Maybe even with different OS-dependent implementations.

Yes, you can hide it with a password buried in the server code. But the only really secure way is to type in the password on the console each time the server starts. And hope that there is no key logger.

There are other much more secure options. Some examples:

  1. Encrypt the passwords, store the key to decrypt the passwords in a HSM. Overwrite the passwords in memory after usage.
  2. Similar to option 1 but with smartcards. You can then even require multiple smartcards to unlock the secrets by using Shamir's secret sharing algorithm.
  3. Use a central password vault with a short-lived API key.