Encrypt with GPG without adding stuff to the encrypted file? - cryptography

$ echo "helloworld" > text.txt
$ cat text.txt
helloworld
$ gpg --cipher-algo AES256 --symmetric --armor text.txt
gpg: gpg-agent is not available in this session
$ ls
text.txt text.txt.asc
$ cat text.txt.asc
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1
jA0ECQMCnGyzh+mRmpBg0kgBfcqLbdAhLc+xwZDta3/kudi/f6MmjXUzFUbNFr3H
IoXgqzjRqbeNESHd+nFSTxHQc8tXF80vXMdDzTy3HmD6ZWk3BvVx5Vo=
=EviP
-----END PGP MESSAGE-----
So, how can I avoid adding GPG stuff? I want only the encrypted bytes.
As AES256 is symmetric, I'd like to do something like this:
1. Apply AES with keyA to "file_original.txt" and produce "file_keyA.txt"
2. Apply AES with keyB to "file_keyA.txt" and get "file_keyA_keyB.txt"
3. Apply AES with keyA to "file_keyA_keyB.txt" and get "file_keyB.txt"
4. Apply AES with keyB to "file_keyB" and get "file_original.txt"
So, if I'm A, and want to send "sometext" to my friend B:
I send "sometext" encrypted with GPG with keyA to my friend.
He send back to me his text encrypted with his keyB too.
I decrypt with my keyA and send back to him.
He should apply keyB and get "sometext".
It should be possible if I use gpg with AES and my friend another software or another symmetric algorithm without knowing my keyA. But it's only possible if gpg (or his software) doesn't add stuff to the encrypted file. I want to apply only the algorithm AES, so I can encrypt multiple times with the same key and get the original.

Probably you want to use openssl instead of gnupg. For example:
openssl enc -aes128 -salt -in yyy -out yyy.enc
More information at the manpage: https://www.openssl.org/docs/man1.0.2/apps/enc.html

If you're looking to send an encrypted message to your friend with gpg, without sharing a passphrase that'd be used to decrypt the message, then you probably want to use asymmetric encryption. To do this, you and your friend will each need to generate PGP keys with
gpg --gen-key
then exchange your public keys
gpg -a --export "mykey" > mykey.pub
<trade mykey.pub files>
gpg --import theirkey.pub
then prepare your message for transmission
gpg -e -a -u "my key" -r "their key" --sign -o somefile.txt.gpg somefile.txt
after your friend has the message they'll need to decrypt it with
gpg -d -o somefile.txt somefile.txt.gpg
and they've got the message. GnuPG will generate a strong key, use that key to encrypt the message, then use your friend's key to encrypt that key and attach it to the file. It'll also use your private key to sign the file so your friend can be (reasonably) sure it wasn't tampered with in transit. In this example you can use
gpg --list-keys <or gpg -k>
to find their key handle (it's the bit after "rsa4096/" and before the creation date) to use in the quotes in the -r "their key" part, and
gpg --list-secret-keys <or gpg -K>
to find the handle of your key, to use in the -u "my key" part.
If you're really looking to use symmetric encryption and share a passphrase with your friend, then I'd also recommend openssl, like #pchris suggested.

Related

How can I obtain the known_hosts formatted public key value for ec2 instance ssh-key?

AWS outputs this key line 2048 SHA256:2p2o3eIz/XxxX6IIegXx5FkHo3Lap7xR+Ue2qJ0zV4w root#ip-****** (RSA) to the system log. How can I replicate this format for the ssh-rsa key from the command line? I was scraping the logs until I realized that you can't rely on ec2's console-log fetching command because it's buffered and only stores a small amount of the output.
To clarify the ssh-key file in question is a PEM style file with the beginning and ending tags for a base64 encoded ----RSA PRIVATE KEY----
If it's helpful to know the ssh-rsa line value for the public key is base64 encoded.
I've tried...
sudo ssh-keygen -E md5 -lf /etc/ssh/ssh_host_rsa_key
2048 MD5:10:b6:fd:21:fb:f4:ca:6b:ef:15:50:15:af:8b:5a:5d root#ip-****** (RSA)
and
sudo ssh-keygen -lf /etc/ssh/ssh_host_rsa_key
2048 SHA256:2p2o3eIz/XxxX6IIegXx5FkHo3Lap7xR+Ue2qJ0zV4w root#ip-****** (RSA)
But neither produce output looking
-----BEGIN SSH HOST KEY KEYS-----
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7+hIGwj+cfT6tLdaVuUewnY/NwoQUdAaLw30auAHQS1B/HAEEJ+f+iLjC7JM2IV00Pgbt1trttRmaApghwkB75h0NXArxrfcHTKKV2FO0d8slO9HwDUMbLOEN+L5H0/T0Xtq9u1vnOz2LyMb5KeIywa0HXZ6bGqt1rYCV3Qi369+FUrtTFw8jo8Y21LmqHVltd/d7Kv40Hb3jzqAOCh3jtZ3bilenMA9pAtXM+XJP54oS6z0NutDJLU2n1DVg2q+5wwjJJqljgYg98t5Xj8VmGlWrtam6FMcaSJ77UwMyxLsSe/Ow7DYGAMrd6PLY5RA1stj4W0WYeB8IOSgyGWPf root#ip-******
-----END SSH HOST KEY KEYS-----
I had an ah-ha moment.
You can just use ssh-keyscan -t rsa localhost to generate the known_hosts key entry for the rsa public key of the server. Since I'm logging into the ec2 instance now instead of trying to scrape the logs I can just trust the results.

How can I determine the format of an ssh private key file?

I am developing an application that uses ssh keys (JSch), and it won't accept some ssh keys. I want to make guidelines to users so they know which keys they can use and which one they can't. Hence the question: how can I determine the format of an ssh private key file, going beyond the RSA/etc and the number of bits?
For instance, at the end of this question is a 3072 bit RSA key that was generated using ssh-keygen with no parameters on android/termux. it works in ssh but both JSch and JuiceSSH refuse to even open it. openssl rsa -text -noout -in file says:
unable to load Private Key
1991864336:error:0909006C:PEM routines:get_name:no start line:../crypto/pem/pem_lib.c:745:Expecting: ANY PRIVATE KEY
I can fix this by running ssh-keygen -p -m PEM -f file, and this might be a workaround for some users, but it would help to know in advance which formats work and which don't.
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

PAM module that uses SSH

Is there a PAM module that can authenticate a user with an SSH challenge-response?
I'm trying to write a PAM aware application that essentially has the same authentication process as an SSH connection. I have been unable to find a PAM module that already does this (the pam_ssh module is still password-based), so I have been attempting to write my own.
However, I cannot find an API that will allow me to access SSH in this way. Even with a PAM module for sshd, there doesn't seem to be a clean way of verifying an SSH public key.
To be more explicit, if I am given an SSH public key for a given user on a machine (consider localhost for simplicity), I want to send a challenge to that user on that machine to test if they own that SSH key. Does anyone know a way of doing this?
Thank you!
You could encrypt some random data using the public key, send it to the user, and assert that they are able to decrypt it with the private key. If you're using RSA keys, you can perform the encryption/decryption with OpenSSL. For example,
# server
$ ssh-keygen -e -m PKCS8 -f ~/.ssh/id_rsa.pub >pub.pem
$ openssl rsautl -pubin -inkey pub.pem -encrypt -pkcs -in random -out encrypted
# client
$ openssl rsautl -inkey ~/.ssh/id_rsa -decrypt -in encrypted -out random
and verify that the client is able to reply with the correct contents of random.
These commands are inspired by jass, which you could use instead of ssh-keygen+openssl.
Unfortunately, this doesn't work with Ed25519 keys; OpenSSH has its own custom format and doesn't have a way to convert them.

How to gpg encrypt with ssh public key?

I have a public key in a file called key.pub, and the contents look like:
ssh-rsa AAAAB...<snip>...t+f klahnakoski
I would like to to use it to encrypt a file with gpg. What is the sequence of shell commands required?
I imagine the sequence looks something like:
convert key to gpg-friendly format
invent some credentials to sign key with
invent a user to facilitate adding key to keyring
perform the encryption
Thank you!
RSA keys can only be used to encrypt a proportion of their key length. e.g. a 2048 bit RSA key can only be used to encrypt about 245 bytes.
See:
https://security.stackexchange.com/questions/33434/rsa-maximum-bytes-to-encrypt-comparison-to-aes-in-terms-of-security
So to encrypt / decrypt large amounts of data (files) you would use a symmetric key which was encrypted using a public key, not the public key itself.
Also, you wouldn't add a symmetric key to a public SSH key, because the the symmetric key is a secret, and the public SSH key isn't a secret. The symmetric key should be added to the private SSH key.
It goes something like the following:
To convert the file format, install the monkeysphere tool set (Ubuntu)
sudo apt-get install monkeysphere
Use the pem2openpgp tool to convert the private key to gpg format. Pipe to gpg for import.
pem2openpgp userid-ssh#example.com < id_rsa | gpg --import
# Check it's there
gpg --list-secret-keys
Edit the trust level you have in the key.
gpg --edit-key userid-ssh#example.com
gpg> trust
Add the trust level you need (ultimate for example)
The key imported is only suitable for creating certificates, not for signing or encryption.
Encryption
The key is an RSA key and can't be used to encrypt / decrypt large amounts of data. If you want to do that you have to add a symmetric encryption subkey. When you encrypt, GPG will use this subkey rather than the original SSH key.
gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
Your selection? 6
Now you can encrypt and decrypt using the identity based on the SSH key.
gpg -vv -r userid-ssh#example.com -e -a unencrypted_file.txt
So how useful is this?
Well, it makes more sense to use GPG to generate and manage your SSH keys as authentication subkeys rather than trying to do it the other way round. In fact it can be integrated into SSH instead of ssh-agent.
Probably ssh-vault could give you some ideas, it follows the same principle of PGP and using the public ssh keys to encrypt the password only.

DSA vs RSA: how can you tell

Does anyone have a tool to use in order to differentiate an RSA public key vs a DSA public key? I have two SSH .pub files and i need to know if they're RSA or DSA.
As noted in the other answer, since the file is in SSH.COM format, you can convert to openssh format and just open the file to check for ssh-dsa or ssh-rsa:
To convert your SSH.COM key to OpenSSH format use:
ssh-keygen -i -f ssh_key.pub
From the ssh-keygen manpage
-i This option will read an unencrypted private (or public) key
file in SSH2-compatible format and print an OpenSSH
compatible private (or public) key to stdout. ssh-keygen
also reads the `SECSH Public Key File Format'. This option
allows importing keys from several commercial SSH
implementations.
-f Specifies the filename of the key file.
Source: http://landru.uwaterloo.ca/cgi-bin/wiki.pl?OpenSSH_-_SSH.Com_Interoperability
You can use ssh-keygen to get a fingerprint and type out of a .pub file:
ssh-keygen -lf id_rsa.pub