vault kv put/write binary data - hashicorp-vault

I have a enc file that I generate using openssl like so.
openssl enc -aes-256-cbc -md sha1 -pass file:/tmp/keyfile.key \
-in /tmp/keyfile \
-out /tmp/keyfile.enc
I want to store the keyfile.enc file as secret in vault. I tried
cat keyfile.enc | vault kv put secret/mysecret key=-
Does kv put/write work with binary data ?
I want to use the vault mutating webhook to mount the secret into a container ultimately.

https://discuss.hashicorp.com/t/loading-storing-binary-files-as-secrets/22636
Got my answer. Yes we cannot use binary files, base64 encode them

Related

Secure openSSL file encryption

I wish to encrypt gigabytes of data with OpenSSL (multiple files), securely.
I use this command (openSSL 1.0.2p-i386-win32):
openssl.exe enc -e -aes-256-ctr -in secret.txt -out encrypted.txt -salt -pass pass:AsIDHnd19!&###!#lJglG1f31!
My questions are:
What mode to use? CTR or CBC? (CTR for speed?)
How to generate random IVs? For example in a PowerShell script. (I am using Pshell v2.0)
Is the command I provided secure enough?
Can I use the same salt for every file, for better encryption speed?
Does a 20-30 char truly random password compensate for the lack of
IV?
EDIT:
I downloaded a newer version, with ability to use PBKDF2 (openSSL 1.1.1-win32-mingw):
openssl.exe enc -e -aes-256-ctr -in secret.txt -out encrypted.txt -salt -pass pass:AsIDHnd19!&###!#lJglG1f31! -pbkdf2 -p
With -p I can see the salt, key and IV that's used to encrypt the file. All 3 parameters change every time I run openssl, even if on the same file and with the same pass.
Does that mean I'm safe now and IV is random?
CBC and CTR should have same speed around.
If not specified IV is generated from your password with pbkdf2.
CTR is recommended to CBC.
Using the same salt is not adviced. Salt used to prevent attacks for the password, from OpenSSL documentation.
Without the -salt option it is possible to perform efficient dictionary attacks on the password and to attack stream cipher encrypted data. The reason for this is that without the salt the same password always generates the same encryption key. When the salt is being used the first eight bytes of the encrypted data are reserved for the salt: it is generated at random when encrypting a file and read from the encrypted file when it is decrypted.
IV is not lack of. OpenSLL generates is for you if not given.

How do I find the join command for kubeadm on the master?

I've lost the original 'kubeadm join' command when I previously ran kubeadm init.
How can I retrieve this value again?
kubeadm token create --print-join-command
To print a join command for a new worker node use:
kubeadm token create --print-join-command
But if you need to join a new control plane node, you need to recreate a new key for the control plane join command. This can be done with three simple steps:
Re upload certificates in the already working master node with kubeadm init phase upload-certs --upload-certs. That will generate a new certificate key.
Print join command in the already working master node with kubeadm token create --print-join-command.
Join a new control plane node with $JOIN_COMMAND_FROM_STEP2 --control-plane --certificate-key $KEY_FROM_STEP1.
This might not work for the old Kubernetes versions but I tried with the new version and it worked for me.
To create kubeadm join command, please run the following commands:
Step 1 - Retrieve Token CA Hash:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt \
| openssl rsa -pubin -outform der 2>/dev/null \
| openssl dgst -sha256 -hex \
| sed 's/^.* //'
This command will provide you public key.
Step 2 - Retrieve bootstrap Tokens:
kubeadm token list
This will print all tokens, so copy the token value under TOKEN with the description "The default bootstrap token generated by kubeadm init."
Step 3 - Creates kubeadm init command:
Now use following syntax to create join command without creating a new token:
kubeadm join <ip-address>:6443\
--token=<token-from-step-2> \
--discovery-token-ca-cert-hash sha256:<ca-hash-from-step-1>
kubeadm token create command creates a new token, in this case without any description, so for you not to create any additional tokens, just pick the token which has a DESCRIPTION as mentioned in Step 2.
Run the below command on your master node machine.
kubeadm token create --print-join-command
This command will generate the new token as well as the join command which you can use at your worker node to join the cluster.
Building off #Abhishek Jain's answer, here's a script to print the kubeadm join command with a little help from jq:
# get the join command from the kube master
CERT_HASH=$(openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt \
| openssl rsa -pubin -outform der 2>/dev/null \
| openssl dgst -sha256 -hex \
| sed 's/^.* //')
TOKEN=$(kubeadm token list -o json | jq -r '.token' | head -1)
IP=$(kubectl get nodes -lnode-role.kubernetes.io/master -o json \
| jq -r '.items[0].status.addresses[] | select(.type=="InternalIP") | .address')
PORT=6443
echo "sudo kubeadm join $IP:$PORT \
--token=$TOKEN --discovery-token-ca-cert-hash sha256:$CERT_HASH"
If you are joining control plane nodes, you will need a certificate key in the command too:
kubeadm token create \
--print-join-command \
--certificate-key \
$(kubeadm alpha certs certificate-key)
The kubeadm alpha certs certificate-key command will generate a new certificate key on demand as per the documentation here
To Join a worker node, the command kubeadm token create --print-join-command given in the accepted answer is sufficient
Here is a bash script that automate this task
read -p 'master ip address : ' ipaddr
sha_token = "$(openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //')"
token = "$(kubeadm token list | awk '{print $1}' | sed -n '2 p')"
echo "kubeadm join $ipaddr:6443 --token=$token --discovery-token-ca-cert-hash sha256:$sha_token"

How to convert X509 certificate and private key in PEM format to GPG format?

I have an X509 certificate (chain) and private key in PEM format. I need to convert them to GPG format so I can use them for signing. How can I do that?
I tried gpgsm, but the keys still don't appear on gpg list of keys.
Please, advise.
From my article
Steps
Break the pfx (p12) into pem files that can be used. For some reason, GPG can't handle standard encoding.
openssl pkcs12 -in sectigo.pfx -nokeys -out gpg-certs.pem
openssl pkcs12 -in sectigo.pfx -nocerts -out gpg-key.pem
Combine the keys into something GPG recognizes
openssl pkcs12 -export -in gpg-certs.pem -inkey gpg-key.pem -out gpg-key.p12
Import into GPG
gpgsm --import gpg-key.p12
At this point we have the p12 imported, and we can see it in Kleopatra, but we can’t use it for PGP operations.
cat gpg-key.pem | PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "Your Name <your#email.address>" > key.pgp
Now!!!! We have a pgp key, and when you import the key.pgp into GPG it will absolutely have the same key as your certificate.
gpg --import key.pgp
It’s separate key storage: gpg has ~/.gnupg/pubring.gpg, gpgsm has ~/.gnupg/pubring.kbx
So keys added with gpgsm aren’t usable with gpg; gpg doesn’t read ~/.gnupg/pubring.kbx.
To see they keys you added with gpgsm, use gpgsm --list-keys. And to create ciphertext from those gpgsm keys, use gpgsm --encrypt. And so on. It’s a completely separate tool from gpg.
As far as importing X.509 stuff for use by gpg, GnuPG doesn’t provide a way to do that. There’s nothing in the OpenPGP standard about it, so there’s no interoperable way to do it.
But the commercial (Symantec) PGP Desktop tool has some way of doing it, so if you can get ahold of a copy of PGP Desktop, I guess you could use that to import your X.509 stuff into PGP Desktop’s key storage, then export it as a .gpg/.asc file, then run gpg --import on that.

How to list the certificates stored in a PKCS12 keystore with keytool?

I wanted to list the certificates stored in a PKCS12 keystore.
The keystore has the extension .pfx
If the keystore is PKCS12 type (.pfx) you have to specify it with -storetype PKCS12 (line breaks added for readability):
keytool -list -v -keystore <path to keystore.pfx> \
-storepass <password> \
-storetype PKCS12
You can also use openssl to accomplish the same thing:
$ openssl pkcs12 -nokeys -info \
-in </path/to/file.pfx> \
-passin pass:<pfx's password>
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Bag Attributes
localKeyID: XX XX XX XX XX XX XX XX XX XX XX XX XX 48 54 A0 47 88 1D 90
friendlyName: jedis-server
subject=/C=US/ST=NC/L=Raleigh/O=XXX Security/OU=XXX/CN=something1
issuer=/C=US/ST=NC/L=Raleigh/O=XXX Security/OU=XXXX/CN=something1
-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
You can list down the entries (certificates details) with the keytool and even you don't need to mention the store type. Also, the .p12 and .pfx are both PKCS#12 files. Assume that you've the keystore file cert.pfx or cert.p12 then you can use the following command to list down the content.
keytool -list -v -keystore cert.pfx -storepass <password>
or
keytool -list -v -keystore cert.p12 -storepass <password>
Keystore type: PKCS12
Keystore provider: SunJSSE
Your keystore contains 1 entry
Alias name: 1
Creation date: Jul 11, 2020
Entry type: PrivateKeyEntry
Certificate chain length: 2
openssl pkcs12 -info -in keystore_file
What is missing in the question and all the answers is that you might need the passphrase to read public data from the PKCS#12 (.pfx) keystore. If you need a passphrase or not depends on how the PKCS#12 file was created. You can check the ASN1 structure of the file (by running it through a ASN1 parser, openssl or certutil can do this too), if the PKCS#7 data (e.g. OID prefix 1.2.840.113549.1.7) is listed as 'encrypted' or with a cipher-spec or if the location of the data in the asn1 tree is below an encrypted node, you won't be able to read it without knowledge of the passphrase. It means your 'openssl pkcs12' command will fail with errors (output depends on the version).
For those wondering why you might be interested in the certificate of a PKCS#12 without knowledge of the passphrase. Imagine you have many keystores and many phassphrases and you are really bad at keeping them organized and you don't want to test all combinations, the certificate inside the file could help you find out which password it might be. Or you are developing software to migrate/renew a keystore and you need to decide in advance which procedure to initiate based on the contained certicate without user interaction.
So the latter examples work without passphrase depending on the PKCS#12 structure.
Just wanted to add that, because I didn't find an answer myself and spend a lot of time to figure it out.

Convert DER encoded certificate to ssh-rsa public key

I am working on a project to automate extracting a public key DER encoded certificate from a users smart card, and convert it to ssh-rsa public key form. The ssh-rsa public key would then be published as a user attribute in AD. From there puppet would grab the ssh public key using an ldap query and place it in the authorized_keys file for the user in question.
The problem I am running into is that in Windows there doesn't seem to be a way to make the conversion from DER encoded .cer file to a ssh-rsa key. If the certificate is moved to the users home directory then it is possible to run:
openssl x509 -inform pem -in username.cer -noout -pubkey > username.pub
Then ssh-keygen can create the ssh-rsa public key using:
ssh-keygen -f username.pub -i -m PKCS8
So does anyone know of a way for windows to make this conversion? If you need more information please let me know.
You need to convert the DER encoded file to PEM first. Here is what you would need to do:
openssl x509 -in <your DER encoded File> -inform DER -out username.crt -outform PEM
There is a way, you need to use:
Import-Certificate
To import the certificate into the users/local machine store. You can then get the public key like so (well this gets the public key for every cert that has one, so change it to suite your needs):
((get-childitem cert:\LocalMachine -Recurse) | Where-Object{$_.PublicKey}).GetPublicKey()
This is using PowerShell 3.