pteich / caddy-tlsconsul

🔒 Consul K/V storage for Caddy Web Server / Certmagic TLS data
Apache License 2.0
96 stars 17 forks source link

Is it possible Decrypt/decompress certificates #17

Closed traskat closed 2 years ago

traskat commented 3 years ago

it seems that the consul storage extension for caddy is gzipping or encrypting the certs in consul.

Is it possible to get the plain certs/ out of consul?

admin.backbiosis.com.crt admin.backbiosis.com.json admin.backbiosis.com.key

i tried to unzip the files but get this error:

./consul kv get caddy/certificates/acme-staging-v02.api.letsencrypt.org-directory/admin.backbiosis.com/admin.backbisosis.com.crt | gunzip -dc > cert.crt

gzip: stdin: not in gzip format`

i reissued the certs a couple of times just to make sure the certs are broken. but still cannot decompress/decrypt the files

the ssl endpoint works with the certs tho.

dafanasiev commented 3 years ago

@traskat maybe you use Default AES Key ?

traskat commented 3 years ago

tried that already. but not sure i tried the right openssl command. ~/tmp/encrypted_cert.crt | openssl enc -d -aes-256-cbc -md md5 and witht that i will always get bad magic number

dafanasiev commented 3 years ago

code use GCM, not CBC mode. I think that you cant decrypt data with openssl cli....(not sure)

I write PoC for decryption (but no time to test it):

package main

import (
    "encoding/base64"
    "fmt"
    "github.com/pteich/caddy-tlsconsul"
)

func main() {
    fmt.Println("Hello, playground")

    cs := storageconsul.New()
    fmt.Printf("%v", cs)

    c, err := base64.StdEncoding.DecodeString("base64-data-of-cert-saved-in-consul")
    if err != nil {
        panic(err)
    }

    sd, err := cs.DecryptStorageData(c)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%s", string(sd.Value))
}
traskat commented 3 years ago

i am not that familiar with go but will try to get it to work and let you know. thanks already for the PoC

traskat commented 3 years ago

tried to with you PoC doesn't wrk work that well since there is no base64 invloved here is something i put together but still doesn't work.

package main

import (
   //"encoding/base64"
   "io/ioutil"
   //"encoding/hex"
   "fmt"
   "github.com/pteich/caddy-tlsconsul"
   //"encoding/json"
)

func main() {
   fmt.Println("Hello, playground")

   cs := storageconsul.New()
     // tested if i can encrypt and decrypt data if i provide them
   /*data := storageconsul.StorageData{
      Value: []byte("testdata"),
   }
   cs := storageconsul.New()
   testData,err := cs.EncryptStorageData(data)

   if err != nil{
      panic(err)
   }
   fmt.Println(testData);*/

   c,err := ioutil.ReadFile("/tmp/crt.out")
   if err != nil {
      panic(err)
   }
   sd, err := cs.DecryptStorageData(c)
   if err != nil {
      panic(err)
   }

   fmt.Printf("########%s", string(sd.Value))
}

i still cannot figure out why i cannot decrypt the data from consul. because the testdata i had worked.

traskat commented 3 years ago

here an updated version which reads directly from consul.

package main

import (
   "fmt"
   "github.com/pteich/caddy-tlsconsul"
   "github.com/hashicorp/consul/api"
)

func main() {
   fmt.Println("Hello, playground")

   cs := storageconsul.New()
   cs.Prefix = "caddy"
   cs.AESKey = []byte("12345678901234567890123456789012")
   client, err := api.NewClient(api.DefaultConfig())
   if err != nil {
      panic(err)
   }

   cs.ConsulClient = client

   c, err := cs.Load("/certificates/acme-staging-v02.api.letsencrypt.org-directory/admin.backbiosis.com/admin.backbiosis.com.crt");

   if err != nil{
      panic(err)
   }

   sd, err := cs.DecryptStorageData(c)
   if err != nil {
      panic(err)
   }

   fmt.Printf("########%s", string(sd.Value))
}

The same aes key is set in the caddy configuration. But still doesn't work to decrypt it with the script. but caddy in general can encrypt and decrypt the files from consul

pteich commented 3 years ago

Hi @traskat Your last code snippet works perfectly - cs.Load() already returns the decoded data. No need to further decode it. Just remove the decoding and just print c (I renamed it to decodedData below):

package main

import (
   "fmt"
   "github.com/pteich/caddy-tlsconsul"
   "github.com/hashicorp/consul/api"
)

func main() {
   fmt.Println("Hello, playground")

   cs := storageconsul.New()
   cs.Prefix = "caddy"
   cs.AESKey = []byte("12345678901234567890123456789012")
   client, err := api.NewClient(api.DefaultConfig())
   if err != nil {
      panic(err)
   }

   cs.ConsulClient = client

   decodedData, err := cs.Load("/certificates/acme-staging-v02.api.letsencrypt.org-directory/admin.backbiosis.com/admin.backbiosis.com.crt");
   if err != nil{
      panic(err)
   }

   fmt.Printf("########%s", string(decodedData))
}