-1

What specific syntax must be changed in the bash below to successfully decode the base64 encoded value which is throwing the error below?

THE ERROR:

The following 3 simple commands are typed into the terminal of a RHEL 8 vm running in Azure:

[user@myVM ~]$ myVar=$(az keyvault secret show --name "secretName" --vault-name "vaultName" --query "value")
[user@myVM ~]$ echo $myVar
"very.long.base64.encoded.string.representing.the.original.yaml"
[user@myVM ~]$ echo $myVar | base64 --decode
base64: invalid input

The second command prints what looks like valid base64 encoding of a long string, perhaps a few hundred characters or more encoded.

The error base64: invalid input seems to indicate that the base64 program is not able to accept the encoded input into its decode command.

THE SOURCE DATA:

The contents of the base64 encoded data above originated in a yaml file with perhaps 20 lines, which was passed through terraform's fileBase64() command as follows before the VM was created:

resource "azurerm_key_vault_secret" "secretName" {
  name         = "secretName"
  value        = filebase64(var.keySourceFile) 
  key_vault_id = azurerm_key_vault.vaultName.id
}

RESULTS OF TRYING USER SUGGESTIONS:

Per @roaima suggestion, we tried the following:

[user@myVM ~]$ az keyvault secret show --name "secretName" --vault-name "vaultName" --query "value"
"very.long.base64.encoded.string.representing.the.original.yaml=="
[user@myVM ~]$ myVar=$(az keyvault secret show --name "secretName" --vault-name "vaultName" --query "value")
[user@myVM ~]$ echo "$myVar" | base64 --decode >/dev/null 
base64: invalid input 

As you can see, we validated that a long encoded string is presented by the raw command before we put it into myVar . Note that it ends with == and is surrounded by double-quotes.

The raw data in the original source file that was sent into terraform looks something like:

secret1: value1
secret2: value2 
...
secretN: valueN

Then we tried the following but you can see nothing was returned:

[user@myVM ~]$ printf '%s\n' "$myVar" | base64 --decode --ignore-garbage >/dev/null
[user@myVM ~]$
CodeMed
  • 5,199
  • Can you show the real value of $myVar? – Arkadiusz Drabczyk Apr 14 '22 at 22:04
  • @CodeMed, the way it's now, the post makes it look like your actual data is "very.long.base64.encoded.string.representing.the.original.yaml", which doesn't look base64-encoded. In fact it looks like a test string where the encoding wasn't done for some reason. Note also that you haven't mentioned that string is a placeholder even in the text. Inaccurate data like that leads the reader in quite a wrong direction, and there's already enough bad questions on SE sites. If you can't show the real data, come up with something you can show, e.g. a throwaway secret or something like that. – ilkkachu Apr 15 '22 at 09:01
  • hmmh, the part with "very.long.base64.encoded.string.representing.the.original.yaml==" is even worse. Base64-encoding adds = signs for padding, but here, they're inside the quotes. Does that mean the output has the literal quotes there, or that they're part of the placeholder text? The reader can't know. Anyone coming to this question later to see if it helps with their issue can't know. – ilkkachu Apr 15 '22 at 09:24
  • If you can't create throwaway data to show, what you could do would be to show data that's actually structurally valid as base64, with the same structure as the actual data. E.g. instead of showing c2VjcmV0cwo=, run it through tr a-zA-Z0-9+/ A, giving AAAAAAAAAAA=. Or something like that. And then say you did exactly that. Hiding the facts when trying to discuss a technical issue doesn't help. – ilkkachu Apr 15 '22 at 09:29
  • @ilkkachu Another user simply answered the question based on the information provided instead of adding all your unnecessary chatter. – CodeMed Apr 15 '22 at 19:42
  • @CodeMed, so, you think suggestions on how to improve your questions to make them easier for the unpaid strangers reading them to help you, or to make them more useful for future readers are unnecessary? Can you understand the idea of having SE posts actually be useful for other people too, and not just the original poster? If you think that's unnecessary, you're just being selfish. (Actually, I wonder if you even know yourself what the actual issue here is, or if you even care about getting a big picture.) – ilkkachu Apr 15 '22 at 20:46
  • @CodeMed, consider that I just straight up gave you a command you could use to conceal the actual important data. It doesn't get easier than that. – ilkkachu Apr 15 '22 at 20:47
  • @ilkkachu Chattiness above distracts other users from the very clear problem definition and answer that are each fine as they are. Please delete your chatty comments to clean up the site. – CodeMed Apr 16 '22 at 21:06

1 Answers1

3

Always double-quote your variables when you use them*.

Repeatable example

myVar=$(perl -e 'print "hello, world. " x100, "\n"' | base64)
echo "$myVar"

echo $myVar | base64 --decode >/dev/null # Fails base64: invalid input

echo "$myVar" | base64 --decode >/dev/null # Works

What's happening is that the quoted variable produces N lines of 76 characters, but the unquoted variable produces 1 line of 76 x N characters plus a space between each group of 76. This second output is not valid base64 format.

Reading comments and feedback, it seems that the source base64 data is still not completely compatible with the base64 command. In this instance it's necessary to skip unexpected characters:

printf '%s' "$myVar" | base64 --decode --ignore-garbage

Here I have also switched from using echo to printf (without a trailing newline) so that the output is better controlled.


* Except when you really know you have a necessary reason not to quote. These cases are few and far between. If in doubt, quote.

Chris Davies
  • 116,213
  • 16
  • 160
  • 287
  • We just posted the results of trying your suggestion to the end of the OP. What do you suggest? – CodeMed Apr 14 '22 at 22:21
  • @CodeMed man base64 offers the -i flag that can when decoding, ignore non-alphabet characters. I'd try that along with avoiding echo. So, printf '%s\n' "$myVar" | base64 --decode --ignore-garbage >/dev/null – Chris Davies Apr 14 '22 at 22:34
  • We just posted the results of printf '%s\n' "$myVar" | base64 --decode --ignore-garbage >/dev/null to the end of the OP, but you can see it did not return anything. Though the echo $myVar command DOES return the long encoded string. What else might we try? – CodeMed Apr 14 '22 at 22:40
  • Did you still get the error? – Chris Davies Apr 14 '22 at 22:45
  • No output results at all when we add --ignore-garbage, as shown in what we added to the end of the OP. No error, but nothing useful either. – CodeMed Apr 14 '22 at 22:51
  • 2
    @CodeMed do you understand the meaning of > /dev/null? This is basic UNIX/Linux and is used to discard stdout output from the command. In this case I used it so that only an error would be output (if one was generated) without having it lost in a large amount of normal output. Obviously you'd remove it to get the data. – Chris Davies Apr 14 '22 at 22:52
  • Thank you and +1 for meeting us where we are on this instead of downvoting. Removing > /dev/null while adding --ignore-garbage resulted in the correct data being output to the terminal. This question is now resolved. – CodeMed Apr 14 '22 at 22:55