2

We have a Pivotal Cloud Foundry server which is configured with a Spring config server with the encryption key. In the corresponding properties file (via github), we have {cipher} prefixed for some simple properties and we are able to get the values just fine in the application. But the challenge we noticed recently is that when we have a base64 data that need to be encrypted, the spring encryption is truncating the trailing equals sign at the end of base64 data. And when our application reads this data, its failing parsing it since its not a valid base64 as its padding character (equals sign) at the end is missing. We tried escaping the equals sign with a backslash but still no luck. We are just seeing two backslashes, so wondering if there are any suggestions to nail this issue. Thanks!

Astronet-K2
  • 49
  • 1
  • 8
  • How are you trying to encrypt the value? Can you give an example? FYI, If you're running a command from the command line, you might be a victim of shell escaping. If you're on a Linux/Unix shell try using single quotes around your values. – Daniel Mikusa May 19 '20 at 16:03
  • Thanks, here are the details. `VGVzdC0=` is the base64 equivalent of `Test-`, which is my required string. We use the command `curl -k -H "Authorization: $oauth" $config_url/encrypt -d "VGVzdC0="` And when application is getting the value from SprintConfigServer, the value its getting it is `VGVzdC0`. So my base64 parser would fail since its not seeing the mandatory padding character '=' at the end. – Astronet-K2 May 19 '20 at 19:30
  • And we use git bash shell on windows machine. We have been using this shell to encrypt other apps successfully, and generate all our keys for production environments too and we never saw any issues there. Thanks again. – Astronet-K2 May 19 '20 at 19:36
  • Can you share some details about what versions you're using here? Are you using an OSS Spring Cloud Config Server or Pivotal's Spring Cloud Config Server? In your client app, what versions of Spring Boot, Spring Cloud, and if using Pivotal SCS the Pivotal SCS dependencies? Thanks – Daniel Mikusa May 20 '20 at 20:59
  • We are on Pivotal Sprint Cloud Config Server, v-2.7 (lowers) & v-2.4 (prod). We have TIBCO BusinessWorks Container Edition as well as the SprintBoot services. From the direct properties standpoint, we don't see any issue since the base64 property value is getting interpreted just fine (with = sign at the end), but the only glitch is when this value is getting fed to our services through the Spring Cloud Config Server. So we see that the PCF Spring Cloud Config Server is the culprit. I am also wondering if there is any option to escape the character or something. Thanks @DanielMikusa ! – Astronet-K2 May 21 '20 at 15:05
  • Those version numbers don't match up. Pivotal SCS is 2.0, 2.1, 3.0 and 3.1. See https://network.pivotal.io/products/p-spring-cloud-services/. – Daniel Mikusa May 22 '20 at 16:31
  • @DanielMikusa, Our Spring Cloud Services is v3.1.5. Thanks! – Astronet-K2 May 22 '20 at 18:49

2 Answers2

3

The issue here, as far as I can tell, appears to be with the usage of curl. I'm able to replicate the problem you're seeing by running:

spring decrypt --key @${HOME}/server_rsa_no_eol.key "$(curl -H "Authorization: $(cf oauth-token)" https://config-server.example.com/encrypt -s -d 'VGVzdC0=')"

This uses curl to hit the encrypt endpoint and takes the result and immediately decrypts it with spring decrypt. As you've indicated, this returns VGVzdC0.

It seems like this is a curl issue because I can make the same post to https://httpbin.org/post and I get the same result, VGVzdC0 without the =.

$ curl https://httpbin.org/post --data 'VGVzdC0='
{
  ...
  "form": {
    "VGVzdC0": ""
  },
  ...

What works is if I url encode the = character.

$ curl https://httpbin.org/post --data 'VGVzdC0%3D'
{
  ...
  "form": {
    "VGVzdC0=": ""
  },
  ...

You can also make curl do the url encoding by using --data-urlencode but there's a catch. You must prefix the value with a =. So this also works

$ curl https://httpbin.org/post --data-urlencode '=VGVzdC0='
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "VGVzdC0=": ""
  },
...

From the curl man page:

  --data-urlencode <data>
          (HTTP) This posts data, similar to the other -d, --data options with the exception that this performs URL-encoding.

          To be CGI-compliant, the <data> part should begin with a name followed by a separator and a content specification. The <data> part can be passed to curl using one of the following
          syntaxes:

          content
                 This will make curl URL-encode the content and pass that on. Just be careful so that the content doesn't contain any = or @ symbols, as that will then make the syntax match
                 one of the other cases below!

          =content
                 This will make curl URL-encode the content and pass that on. The preceding = symbol is not included in the data.

The key is the last part =content. That will make curl url encode the content and the prefixed = is not included.

If I repeat my test above, I get the expected result VGVzdC0=.

spring decrypt --key @${HOME}/server_rsa_no_eol.key "$(curl -H "Authorization: $(cf oauth-token)" https://config-server.example.com/encrypt -s --data-urlencode '=VGVzdC0=')"

As an aside, you can also take the easy option and install the Spring Boot CLI + the Spring Cloud Extension. Then you can just spring encrypt --key @${HOME}/server_rsa_no_eol.key 'VGVzdC0=' and you'll get the right values. That does mean you need a copy of the key on your local machine though, which you may or may not have.

brew install springboot
spring install org.springframework.cloud:spring-cloud-cli:2.2.1.RELEASE
halfer
  • 19,824
  • 17
  • 99
  • 186
Daniel Mikusa
  • 13,716
  • 1
  • 22
  • 28
0

You can avoid the problems caused by curl by using httpie:

Encrypt:

echo -n cleartext | http https://config-server.com/encrypt

Decrypt:

echo -n ciphertext | http https://config-server.com/decrypt
Ortomala Lokni
  • 56,620
  • 24
  • 188
  • 240