net/http TLS issue

243 views
Skip to first unread message

Rich

unread,
Oct 16, 2020, 5:05:23 PM10/16/20
to golang-nuts
I don't know if we're the only company on the planet that demands the https keys have a passcode to them but I've been having a heck of a time trying to find a good way to serve https using a key with a passphrase.  

err := ListenAndServeTLS(addr, certFile, keyFile string, handler Handler)  

If they keyFile has a passcode this doesn't work and the examples I've seen take this one line and turn it into a much longer chunk of code.

Marcin Romaszewicz

unread,
Oct 16, 2020, 6:33:14 PM10/16/20
to Rich, golang-nuts
Having a passcode to protect a key file for a production service is pointless, because you move the problem of storing the certificate securely to the problem of storing the passcode securely, so might as well skip the passcode and store the cert securely.

Your certificate is probably encoded as a PEM cert, so you'd have to manually call https://golang.org/pkg/crypto/x509/#DecryptPEMBlock and provide a password, then construct your listener yourself using the unmarshaled certificate. So, how are you going to protect this passcode? Is someone going to have to provide it every time you start?

Generally, in production systems, we use some kind of secret manager to store that certificate, such as AWS Secrets Manager or encrypt it with KMS, store it in Vault, etc. Ideally, you actually make a subordinate cert for that service and rotate it at a reasonable interval.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/c75fc8f6-abe4-4614-8281-cef4cb315ac3n%40googlegroups.com.

Rich

unread,
Oct 18, 2020, 4:39:46 PM10/18/20
to golang-nuts
Thanks for your reply, however as I stated it's company policy to have a passphrase, even our java. keystores have a passcode. Using other services or methods, or just not having a passcode -- Just not the way they want it done. I am not a part of the security team that makes this stuff up and you might as well try to get water to flow up hill to change policies. It is what it is, I gotta deal with it. 

I have no problem writing this myself and I already have ideas on what I am going to do, but before I do that I thought I'd ask and see if anyone knew of a package, or some easier way that did this already. I've spent hours in the past writing code only to find later someone has written a great package that does what I need and more. Never hurts to ask right ;)

pat2...@gmail.com

unread,
Oct 18, 2020, 9:01:23 PM10/18/20
to golang-nuts
On Sunday, October 18, 2020 at 4:39:46 PM UTC-4 Rich wrote:
I have no problem writing this myself and I already have ideas on what I am going to do, but before I do that I thought I'd ask and see if anyone knew of a package, or some easier way that did this already. I've spent hours in the past writing code only to find later someone has written a great package that does what I need and more. Never hurts to ask right ;

The great packages have been written. But the real solution is to use a service either in software like AWS Secrets Manager or in a hardware box like the banking networks like.  If your company has had this policy a long time, use whatever other systems have used. 

Writing crypto software that seems to work is not hard. For this case, have the operator enter a passphrase, run it thru a HMAC, and then use AES 256 to encipher/decipher the CERT. Store the binary in some standard format, try to avoid ANS.1 if you can possibly do it.

Writing crypto software that really works, is secure, etc. is very hard. No offense, but you are unlikely to do it.

I don't understand how this is supposed to work. Do you ask the system's operator to type in the passphrase every time the service is restarted? Most modern systems don't have a human operator to do such typing. And how do you ensure that there is no keyboard logger on the operator's terminal? Or are you keeping the passphrase in someplace like an environment variable or a secret file?

The software and the crypto are only a tiny part of the issue. Either do whatever made them happy in the past, or find out what is really driving this "requirement".

Rich

unread,
Oct 19, 2020, 1:34:17 PM10/19/20
to golang-nuts
Thanks for your reply. I think I have it down now. What I am going to do is: 
1. Read the key in to pemBlk
2. See if it's got a passcode
3. If it does decrypt
```
if x509.IsEncryptedPEMBlock(pemBlk) {
    keyPEMBlock, err = x509.DecryptPEMBlock(pemBlk, []byte(passphrase))
```

As to having to have a human enter the passcode on each restart. I have a json configuration file that contains directives for where the keypair is an the passphrase. Read the passcode, try to decrypt it.  If the decrypt fails -- its probably in clear text so encrypt it and write it back to the config file. This way all the person has to do is put the passphrase in clear text, restart application, password is now encrypted in the config file. When the password changes because the key changed (once a year), change the config (plaintext) and restart -- passphrase is then encrypted. 

Brian Candler

unread,
Oct 20, 2020, 4:12:33 AM10/20/20
to golang-nuts
What key do you use to encrypt and decrypt the password in the config file?  Something hard-coded in the application?  That'll be easy to extract, e.g. by single-stepping the binary.

It's also worth mentioning: with many filesystems, when you overwrite a file, garbage blocks containing the old file (and hence the cleartext passphrase) remain on the system.  This will be true for pretty much any filesystem if you decide to do an atomic overwrite of the config file by writing out a new file, and then renaming it to replace the old file.  The directory entry is updated to point to the new file, but the blocks which contain the old file remain until they are re-used at some indeterminate time in the future.
Reply all
Reply to author
Forward
0 new messages