Is there an alternative to using ProtectKeysWithCertificate? - asp.net-core

My web application is now running on multiple Unix containers (pods), so I had to add a centralized place to share the keys between all pods using AddDataProtection(),
I'm using PersistKeysToDbContext(), but this problem is even worse when saving to a file share,
Without ProtectKeysWithCertificate() the keys are unprotected - nobody wants that
<!-- Warning: the key below is in an unencrypted form. -->
If I use a certificate it gets encrypted just fine, but I prefer not to have to depend on another certificate,
services.AddDataProtection()
.SetApplicationName(dataProtectionSettings.ApplicationName)
.PersistKeysToDbContext<DataProtectionContext>()
.ProtectKeysWithCertificate(serviceCertificate)
.UnprotectKeysWithAnyCertificate(serviceCertificate);
I wonder why the key is not just AES encrypted using a password (why does it require certificate)
Is there an alternative? or, what would it take to override this process and implement AES encrypt/decrypt based on a password?

Related

Public Key Authentication

I have been designing a blockchain based cryptocurrency and some of the blocks on the blockchain can have their data updated by the owner of the block. I tried implementing an ssh style of public key authentication: client generates a key pair and sends the public key over to the block where it allows the public keys listed under "admins" to change meta data of the block. The problem with this is that someone can send random known public keys to see if they are allowed to edit meta data, how does ssh prevent people from just sending some sort of string with a known public key to access the contents of the ssh? (I ask this because I want to implement something similar to my context)
Not sure if this is really a programming question, but:
SSH uses publickey keys to authenticate 'hosts' (servers) always and 'users' (clients) optionally (but often). The commonly used and de-facto standard implementation OpenSSH, for the latter case, uses a file for each user on the server, normally located under the user's home directory as $HOME/.ssh/authorized_keys, which lists the publickeys valid for that user. If the client process specifies a username and a publickey listed in that user's authorized_keys file, and uses the privatekey to sign certain data including a connection secret and nonces, that is considered to prove the identity of the user. (See RFC 4252 for details, but start with 4253 for context.) Other implementations need to have equivalent data, although not necessarily that exact file. The host/server usually allows the user/client to make several attempts, in case it has multiple keys and/or other methods to try, but this is configurable.
SSH by itself mostly doesn't control access; it just establishes the user/client's identity as a username configured on the 'host'. Using that identity to control access -- what security people call authorization as opposed to identification and authentication -- depends on the host. Many SSH hosts are Unix, and for Unix the same rules apply to accessing Unix over SSH as apply to other kinds of connection: this starts with the classic 'chmod bits' on each file allowing read,write,execute to user,group,other, and can include other things like ACLs, SELinux attributes, sudo rules, group match for signalling processes, special configuration of some things like NFS, and so on and so on. If the SSH host/server is NOT Unix, what security rules or policies it applies once you have connected and authenticated it are up to it and may be quite different.
OpenSSH (on a Unix host) also implements a few options in the authorized_keys file that impose additional restrictions on what the client can do (over that connection); see man sshd on your system or here under AUTHORIZED_KEYS FILE FORMAT. In addition, as noted there, OpenSSH supports a level of indirection: instead of directly listing every key in each applicable user's authorized_keys file you can use a (designated) 'CA' key to sign other keys, and then configure authorized_keys to accept any key signed by a listed CA key. These certificates can themselves include some restrictions; see man ssh-keygen under CERTIFICATES. This can be more convenient in a large environment with many users, hosts, or both.

How do you supply your Applications with TLS Certificates centrally in Openshift?

I am currently struggeling with the following tasks. I don't want to include my TLS certificates in my templates because
I don't want to check in credentials in code management while still checking in the templates
I am using multiple Applications with the same Certificate and I don't want to update repos just because I might distribute another certificate
Now my approach is this. I am using Jenkins for my build pipelines. I have a Repo that is used just for certificate management. It will run when updated and distribute the certificate and private key to Openshift Secrets on various clusters.
When running the Template of an application I am retrieving the Information from the secret and setting the values in the route. And here's where things get tricky. I can only use single line values because
Openshift templates will not accept multiline parameters with oc process
Secrets will not store multiline values
So the solution seemed to be easy. Just store the Certificate with \n and set it in the Route like this. However Openshift will not accept single line certificates resulting in the error
spec.tls.key: Invalid value: "redacted key data": tls: found a certificate rather than a key in the PEM for the private key
Now the solution could be to insert the Certificate as multiple lines directly in the template file before processing and applying it to the cluster but that seems a little bit hacky to me. So my Question is
How can you centrally manage TLS Certificates for your applications and set them correclty in the Templates you're applying?
Secrets can be multiple lines. You can create a secret using a certificate file, and mount that secret as a file into your containers. See here for how to create secrets from files:
https://kubernetes.io/docs/concepts/configuration/secret/
Use the openshift command line tool instead of kubectl.
For certificates, there is something called cert-manager:
https://docs.cert-manager.io/en/latest/
This will generate certs as needed. You might want to take a look.
In order to centrally manage TLS Certificates for the applications, you can create a general secret and use it via volume mounting.

Complications after resetting ssh key

Unfortunately I forgot my id_rsa key passphrase. Since the only solution I found so far is to reset the key by a new SSH key. I now have the problem that I need to add the new key to each server I'm connected to. Is there a possibility to do this automatically? Maybe by copying the information from the "known_hosts" file of the old key to the new one?
This is not quite a duplicate of How to reset or change the passphrase for a GitHub SSH key?, but the answer there is valid.
You have to remember that the whole point of the passphrase mechanism was to prevent access by untrusted hosts. The machinery is specifically setup so only a machine with the proper passphrase (or several) can connect to the server.
The known hosts are only useful to you as a todo list. You need to access one by one somehow (not SSH), to send the new passphrase you generated. The known hosts itself is not the security mechanism, it's just a small part (the less important part, security can do without). It will save you typing some ys in the future.
I'm sorry to say you have to manually get to each machine. If by some miracle you had another vpnish API that all your servers shared you could automate that, but most of us don't.

Modifying SSH Agent for Public Key Signing

I'm trying to get SSH authentication to work without needing to store a private key in plaintext. I'm using an api that allows private key signing of a key stored in memory, and I'm wondering what's the best way to incorporate it into SSH. Since all I really need to do is supply a valid Private key signature to the SSH agent when it's doing its authentication, what would be the best way to do this. Can I just modify the ssh-agent a little bit to accept a signature I give it, or will I have to write my own agent to process this request?
There is a lot of ways to do that. Simplest would be to use PKCS#11 interface, which is available in ssh-agent and can be used for exactly this use case (provide signatures from safe place where the keys are stored -- generally Smartcard or HSM module).
Also encrypted keys using passphrase can solve your requirement against "storing private key in plaintext".

Login to server using WinSCP.com (cmd line) without password

I am using Windows machine and I have WinSCP installed.
I am writing a script that logs in to the server and downloads file.
I do not want to store account password in the script. Is there anyway I can login to server with some-kind of host-key or private-key or something.
Yes, you can use the public key authentication. But for that you still have to store the private key along with your script. Normally the key is encrypted with a passphrase. To automate the login, you would have to store the passphrase to the script file anyway (using the -passphrase switch). So still, if anyone gets an access to your machine, he/she is still able to steal your identity, just as with the password. Though there's an advantage. You can have multiple keys (while only one password). If you use a special key for the script and the key is ever compromised, you can revoke it, while keeping the other keys.
Note that, if you are not absolutely sure of the physical and electronic security of the system on which you are connecting, there's hardly any way to setup an automatic authentication. If you are sure about the security, storing password in the script file is just ok.
Anyway, your question is mostly duplicate of:
How do I setup Public-Key Authentication?
For WinSCP specifics, see the guide to Setting up SSH public key authentication.
See also the WinSCP guide to Protecting credentials used for automation.
I had a similar issue on windows so I used Putty instead http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
If you need to generate a public key then use: http://the.earth.li/~sgtatham/putty/latest/x86/puttygen.exe
I gave the public key + password to whoever owned the SFTP server to install it on his side.
I saved the private key on my side lest say on "C:\privatekey.ppk"
You don't use password on your script but you link to the private which you must have on you machine.
Then, when you want to automate a batch to download from the FTP server the Pageant in order to load the private key into session http://the.earth.li/~sgtatham/putty/latest/x86/pageant.exe
Then use the PSFTP to connect and perform actions http://the.earth.li/~sgtatham/putty/latest/x86/psftp.exe
So here is sample code for the batch file:
!--Loading the key to session--!
#C:\pageant.exe "C:\privatekey.ppk"
!--Calling the PSFTP.exe with the uaser and sftp address + command list file--!
#C:\psftp user#your.server.address -b C:\sftp_cmd.txt
Command list file (sftp_cmd.txt) will like like this:
mget "*.*" !--downloading every thing
!--more commands can follow here
close
Now, all you need to to schedule it in scheduled tasks *I wish it was simple as unix's cron job....