Our config server will be accessed by multiple client applications, due to the security reason, for config server encrypt/decrypt feature, we has to create a keystore (.jks file) with multiple private keys, each key will dedicate to the specific client application. So we don't have to share the same keystore/password among the clients as well as config server. Here are my questions: 1. How to properly configure Config Server's encryption properties, for a single private key, it's much easier because there is only one alias needs to be set, but in our case, we have multiple aliases for the same .jks store

encrypt.keyStore.location=classpath:/xxx.jks encrypt.keyStore.password=xxx encrypt.keyStore.alias=xxxx (there are multiple keys, how can we config this property ?) encrypt.keyStore.secret=xxxx(there are multiple keys, how can we config this property ?) 1. If we use Config Server's /encrypt (or /decrypt) endpoint, how to pass 'alias' (private key) information to the config server so the service will pick the right key to do the encryption/decryption? Any available sample url to share with us?

Any help is highly appreciated!

Comment From: dsyer

Did you read this section in the user guide: http://cloud.spring.io/spring-cloud-static/spring-cloud.html#_using_multiple_keys_and_key_rotation?

Comment From: lipinggm

Thank you Dave. Yes, I read it for couple times, that means to locate a key, we have to put {key:value}{secret:value} in front of each encrypted properties, do you have any sample of using custom SecretLocator for this case?

Regarding to question on how to use Config Server's encrypt/decrypt endpoint with multiple keys, there is a statement under the doc: Spring Cloud Config How config server supports a keystore with multiple private keys for encrypt (or decrypt) feature?

What above statement means? I tried to use http request header or url query string to locate key but neither approach worked.

Thank you so much for any help.

Comment From: lipinggm

I am able to use /encrypt (or /decrypt) to do the encryption (or decryption) when the keystore has multiple keys, we only need to put the following information inside http request body like this: {"key":xxx, "secret":xxx}

For encrypted configurations, we will put {key:xxx}{secret:xxx} prefix by following the instruction indicated in the spring cloud document.

Thanks

Comment From: Jayanta0123

Hey team,

I am reopening this thread, I also need to do a similar exercise using spring-cloud config. Giving you a short description below, please suggest if that's doable in spring config-server or not.

I have multiple teams (team-A, team-B, team-C) using the same config-server. All of them should add their own secrets in the bootstrap file, yml code might look similar to this

``` encrypt: teamA-key: 56ABCD##$% teamB-key: ABDC@3451 teamC-key: BGHdf12341

If I use only one-key, my purpose is served - but I have to share the key across teams. I'm looking for a way to let config-server
reads and understands multiple secret keys in run-time and use them for encryption and decryption.

Please note, I want to stick to **symmetric encryption only**, don't want to take the asymmetric path now.


**Comment From: dsyer**

The relevant section of the User Guide is here: https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#_using_multiple_keys_and_key_rotation (nothing changed).

**Comment From: Jayanta0123**

I tried, no luck yet. Can I use the encrypt and decrypt features of spring-cloud config using multiple keys like above (but without generating the key-store file)?

Using key-store would be the last option which I try. If I find it too complex to work using keystore, I will have to tell the team to use the same key across all apps. 

**Comment From: dsyer**

I guess if you're not using a key store then you need your own `TextEncryptorLocator`. There isn't much demand, so one hasn't been added to the project that works with symmetric encryption. I tried with this and it worked for me:

```java
@Component
@ConfigurationProperties("secrets")
public class SymmetricTextEncryptorLocator implements TextEncryptorLocator {

    private final static String KEY = "key";
    private Map<String, TextEncryptor> encryptors = new HashMap<>();
    private TextEncryptor defaultEncryptor;
    private String defaultAlias = "default";
    private String salt = "deadbeef";

    public SymmetricTextEncryptorLocator(final TextEncryptor defaultEncryptor) {
        this.defaultEncryptor = defaultEncryptor;
    }

    @Override
    public TextEncryptor locate(Map<String, String> keys) {
        String alias = keys.containsKey(KEY) ? keys.get(KEY) : this.defaultAlias;
        if (alias.equals(this.defaultAlias) || !encryptors.containsKey(alias) ) {
            return this.defaultEncryptor;
        } else {
            return encryptors.get(alias);
        }
    }

    public void setKeys(Map<String, String> keys) {
        for (String key : keys.keySet()) {
            this.encryptors.put(key, Encryptors.delux(keys.get(key), this.salt));
        }
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }
}

I can think of various improvements, but you can probably think of the same. The code is here: https://github.com/dsyer/hello-config.

Comment From: Jayanta0123

Thanks Dave. Can we provide this to the end user via spring-framework? That would be a good addition to spring-cloud config.

Comment From: dsyer

Not sure. Probably. It would have to have config settings for the secrets and salts, so something like the above. When you have something that works for you, why not send a pull request?

Comment From: Jayanta0123

@dsyer - my application is actually failing to launch with the ConfigurationProperties and Component annotation.

I have added SymmetricTextEncryptorLocator class, annotating it like above, have declared the encrypt.key and secret.keys in yml file. But getting an error like below.

Spring Cloud Config How config server supports a keystore with multiple private keys for encrypt (or decrypt) feature?

Comment From: dsyer

The exception says it doesn't like a "non-hex character" (probably in the text you obscured). You probably need to fix your YAML.

Comment From: Jayanta0123

encrypt:
  key: market-intelligence-and-rating

secrets:
  keys:
    rx-api-key: D057C5D8E4
  salt: headHoldHigh

This is what I used @dsyer. There's no company-proprietary data - hence I added the plain-texts above.

Configuration properties annotation is causing an issue for me to launch the application

Comment From: dsyer

That looks OK to me, but you haven't shared all your code. Did you copy my code precisely, or did you modify it? The version I wrote would have bound to a string.

Comment From: Jayanta0123

Hello @dsyer ,

I'm able to make the config-server work now - the salt need to be hex-encoded (0...9,a...f), and it need to be of even lengths. These are the two conditions to satisfy.

However, looking at all other aspects, it seems multiple key encryption using a keystore would be more correct approach for me. Thanks for all your help.