Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic questions on Keystore usage

I've got an application which generates SecretKeys, one per client. These need to be persisted in our database. I'm REALLY unfamiliar with common security patterns or implementations, and I'm looking for advice.

The KeyStore class seems to be widely used, especially to protect SecretKeys. However, I've seen little mentioning using KeyStore with databases, and I'm trying to figure out if it's because it's elementary usage (and thus not mentioned), or if it's because this is a bad or redundant approach, and I should really be using a different technique.

The basic design is that each user would have their own keystore, which would be saved/loaded to and from the database by conversion to bytes (using load() and store(), I think).

Anything wrong with this design so far? I'm also wondering how I should handle the password to the KeyStore. We're thinking of only using a single password for all KeyStores, but how do we store THIS securely without a keystore?

This is meant to be used in a back-end app, and the client will never transfer a password to us, nor is there a human operator on the server-side to supply a password.

like image 637
InverseFalcon Avatar asked Jul 27 '10 00:07

InverseFalcon


2 Answers

In the real world, secret keys are stored securely (emphasis mine) in a HSM if they're meant to be stored securely, for an extended period of time (ranging from hours to years). There is the PKCS#11 standard that is meant to aid in interfacing with such systems, but I'll state the least - most HSMs have their own preferred mechanisms for interfacing with the HSM, and the PKCS#11 interface usually turns out to be a crippled one.

Secret keys can also be stored securely in other devices like smart cards and USB tokens, but that is meant for key distribution among a mass populace, rather than key storage for a back-end system.

Not everyone gets a budget for HSMs however, and a lot of other less secure (and obviously cheaper) alternatives are used. Some systems (I'll take the case of the Glassfish application server) store a master password, that is used to protect other passwords. The same holds good for keys - there would be a master key that is used to protect other keys (in a way, this is similar to how HSMs work internally). Of course, you're then stuck with securing the master key. In certain environments, this is easy, as you can place the key in a file that is restricted to a system administrator and the application, and no one else.

Disclaimer: None of this should be treated as advice that is to be ingested blindly :-). If your keys need to be protected at all costs, invest in a HSM.

like image 86
Vineet Reynolds Avatar answered Sep 24 '22 05:09

Vineet Reynolds


So you are using java and keystores.

You have 2 questions I understand correctly?:

1) you need some advice

2) you want to know how to store this stuff to a DB

Answer question1: So when using java and you need to use SSL. Java already has implementations of classes which will communicate over https and it will perform the SSL handshake and everything for you! The only thing you need to do is provide the java.security.KeyStore 's to this implementation.

There are basicly 2 types of keystores:

  • the first is to store all the certificates you trust (multiple certificates)=> Keystore.getInstance("JKS")

  • the second is to hold your client certificate (only one) with it's private key => Keystore.getInstance("PKCS12");

How you make your private keys and certificates, I will not discuss that here. I'm assuming your already there.. (and if not, you can find out). But KeyStores are password protected. So in general they are safe, if nobody can just hack your database. If you store the password to open your keystore in the same table, than watch out for sql injection! But let's assume that's secure.. The keystores provide you the ability to use existing implementation which will handle the SSL handshake. So basically it's not a bad thing to use keystores. Note btw you will only use PKCS12 keystore when there is a need for mutual authentication (meaning you also need to identify yourself).

Answer question2: Yes you can store keystores in the database, it's a bit tricky. Since keystores only allow them to use their store and load methods. But you can achieve this like so:

@Entity
public class MyKeyStoreClass {
private Long id;
@Transient
private KeyStore keystore;
private String passwordForKeyStore;
private Byte[] keyStoreAsBytes;

@PreUpdate
@PrePersist
public void concertKeyStoreToBytes() {
   ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        keystore.store(byteArrayOutputStream,
                passwordForKeyStore.toCharArray());
   keyStoreAsBytes = byteArrayOutputStream.toByteArray();
}

@PostLoad
public void getKeyStore() {
   if (keystore == null && keyStoreAsBytes != null) {
      keyStore = KeyStore.getInstance(getKeystoreType().getType());
      keyStore.load(new ByteArrayInputStream(keystoreAsBytes), passwordForKeyStore.toCharArray()); 
   }    
}

The above code probably isn't 100% correct since I wrote it here (no editor). But it is generally how you could do it, I've done it before and it worked so good luck ;) Note my Spring configuration performs the annotated methods before or after a persist or update. If you don't use annotations and spring, you can achieve this another way..

like image 45
Fico Avatar answered Sep 23 '22 05:09

Fico