7

I'm trying to encode a database string using base64 on the command line in linux.

Once I do I add the value to a secret in kubernetes but my application is failing to connect to the database due to the db string not being accepted. There seems to be a newline getting added when I check the value in lens and this is not there in a similar cluster in the same secret

jdbc:postgresql://test.xxxxxxxx.eu-west-2.rds.amazonaws.com/test

deirdre$ echo jdbc:postgresql://test.xxxxxxxx.eu-west-2.rds.amazonaws.com/test | base64 | tr -d "\n"
amRiYzpwb3N0Z3Jlc3FsOi8vdGVzdC54eHh4eHh4eC5ldS13ZXN0LTIucmRzLmFtYXpvbmF3cy5jb20vdGVzdAo=

Is there something I am doing wrong? or is there an issue with the /?

DeirdreRodgers
  • 367
  • 1
  • 4
  • 17

3 Answers3

13

You can fix those easy with

echo -n "string" | base64

"echo -n" removes the trailing newline character.

You can also see my last answer i gave to following Question Kubernetes secrets as environment variable add space character

bymo
  • 344
  • 1
  • 10
8

the problem is that base64 adds the newline in order to be compatible with older systems that have a maximum line width. you can add the -w 0 option to the base64 command to change the behavior so that it no longer adds new lines.

in your example this would be

echo "jdbc:postgresql://test.xxxxxxxx.eu-west-2.rds.amazonaws.com/test" | base64 -w 0

which results in

amRiYzpwb3N0Z3Jlc3FsOi8vdGVzdC54eHh4eHh4eC5ldS13ZXN0LTIucmRzLmFtYXpvbmF3cy5jb20vdGVzdAo=

edit:

printf "%s" jdbc:postgresql://test.xxxxxxxx.eu-west-2.rds.amazonaws.com/test | base64 -w 0 

produces the correct output which adds an additional newline in the base64 encoded string which is apparently required for the url to be recognized as properly ended

meaningqo
  • 1,653
  • 10
  • 16
  • Hi there, thanks for the reply. I tried that actually but it produces the same encoded value, see how your output is the same as mine above? its really odd – DeirdreRodgers Jun 28 '21 at 14:13
  • 2
    hi. i am sorry, i seem to have missread the question. because base64 also adds additional '\n' characters every 76 characters. can you try using the output of: "printf "%s" jdbc:postgresql://test.xxxxxxxx.eu-west-2.rds.amazonaws.com/test | base64 -w 0" if that doesn't work I am currently out of other ideas – meaningqo Jun 28 '21 at 14:44
1

So please use echo -n to remove the line break before redirecting to base64; and use base64 -w 0 to prevent base64 itself to add line break into the output.

me@host:~ 
$ echo -n mypassword | base64 -w 0
bXlwYXNzd29yZA==me@host:~ # <<<<<<<<<<<<<<< notice that no line break added after "==" due to '-w 0'; so me@host is on the same line
$ echo -n 'mypassword' | base64 -w 0
bXlwYXNzd29yZA==me@host:~ # <<<<<<<<<<<<<<<<<< notice adding single quotes does not affect output, so you can use values containing spaces freely

A good way to verify is using od -c to show the actual chars.

me@host:~ 
$ echo -n bXlwYXNzd29yZA== | base64 -d | od -c
0000000   m   y   p   a   s   s   w   o   r   d
0000012

You see no "\n" is added. But if you use "echo" without "-n", od will show "\n":

me@host:~ 
$ echo mypassword | base64 -w 0
bXlwYXNzd29yZAo=me@host:~ 
$ echo bXlwYXNzd29yZAo= | base64 -d | od -c
0000000   m   y   p   a   s   s   w   o   r   d  \n
0000013

At last, create a function will help you in the future:

base64-encode() {
    if [ -z "$@" ]; then
        echo "Encode string with base64; echoing without line break, and base64 does not print line break neither, to not introducing extra chars while redirecting. Provide the string to encode. "
        return 1
    fi
    echo -n "$@" | base64 -w 0  # here I suppose string if containing space is already quoted
}
WesternGun
  • 11,303
  • 6
  • 88
  • 157