85

So, the scenario is: Given I'm Bob, I want to encrypt some message for Alice. The only public key I have is her ssh-rsa id_rsa.pub like this:

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAyb+qaZLwgC7KAQJzYikf3XtOWuhlMXVv2mbTKa5dp0sHPRd2RaYnH8ZRkt7V8bjqct1IHGCuxI8xyoEp4at3FHe6j9RfWiarc1ldLUCmTtryI0GGpRs6Zpvqdtpcq/1NCIYtUQAvsImyEFCtqmB2suDo1ZSllZQ0x9TCKHdCANYIOeaniuFzR57POgE3vxk/r6PO24oy8BIWqxvi29r0n1LUigVBJ7CmMHuzb4/+i1v6PxV1Lqnj6osPP9GpXpsh8kLUCby/KcmcryWNdSP0esyCdDxkA5hlIuk8qL1vzsyPluUQuc0BEHu6nuw8WQlCF1mFFxcpJL+MhWEr01WIIw== sikachu@Sikachus-Notebook.local

So, is there a way to encrypt a string using this public key so she can use her private key from id_rsa (generated from ssh-keygen) to decrypt the message?

(I know that it's possible right away if you're using .pem key pair file. If you can show me how to convert this to the format that openssl supports, that'd be great as well!)

Thanks!

sikachu
  • 953
  • 1
  • 7
  • 6

6 Answers6

108

It's possible to convert your ssh public key to PEM format(that 'openssl rsautl' can read it):

Example:

ssh-keygen -f ~/.ssh/id_rsa.pub -e -m PKCS8 > id_rsa.pem.pub

Assuming 'myMessage.txt' is your message which should be public-key encrypted.

Then just encrypt your message with openssl rsautl and your converted PEM public-key as you would normally do:

openssl rsautl -encrypt -pubin -inkey id_rsa.pem.pub -ssl -in myMessage.txt -out myEncryptedMessage.txt

The result is your encrypted message in 'myEncryptedMessage.txt'

To test your work to decrypt the with Alice' private key:

openssl rsautl -decrypt -inkey ~/.ssh/id_rsa -in myEncryptedMessage.txt -out myDecryptedMessage.txt
5

Give a try to ssh-vault it uses ssh-rsa public keys to encrypt "create a vault" and the ssh-rsa private key to decrypt "view content of the vault"

nbari
  • 323
2

As of 2024, you can now use age, which supports SSH keys as a recipient. Quoting its docs:

RECIPIENT can be an age public key generated by age-keygen ("age1...") or an SSH public key ("ssh-ed25519 AAAA...", "ssh-rsa AAAA...").

Usage, sender side:

# First, create a file that lists the recipients who should be able
# to decrypt the file. This can be in an authorized_keys format.
# If the recipient uses GitHub, you can download the list of keys
# that the user has registered with GitHub like this:
wget --output-document=recipient.keys https://github.com/dtinth.keys

Then, encrypt the text using age:

echo 'hello' | age --encrypt --armor --recipients-file=recipient.keys

This generates an output like this:

-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IDU1NTU1QSBvVkxk
OWpPT25DVnl1bWIyOXR3R2lIZnhLN3V4QU90d3p3enJSNExKMEV3CmtJcTk0eU5l
RWgrRjF4K1dybks1c1QxRUtyNTBhK211Q0xhTWx6QjJMQnMKLT4gc3NoLWVkMjU1
MTkgRVZQL0JnIHhuaUtWRHpoRGxNUVNTazB2V21sVEZETHVEblJUSHEwKzZKM1FO
UFZhajQKUldTdSt5YityZUdRdkdTRmNCR3RjWkxsalZ1U0xrcDM4NlltazcySFdF
YwotLS0gbCtmZnUvaVhRVWppRDMzd2lrVkFFOWlSb0hHRHhJdENTcitKMTZlam5S
OAqnDBoeJOxujSA1STgI+eta2FnDtuVNo2hDiUrXfxRfpp2Yytt38g==
-----END AGE ENCRYPTED FILE-----

Then, on the receiver side:

# Use age to decrypt the file, supplying SSH identity file.
age --decrypt --identity ~/.ssh/id_ed25519 < mess.age
Thai
  • 261
1

See https://www.bjornjohansen.com/encrypt-file-using-ssh-key. The idea is to generate a single-use symmetric key that is short enough to be encrypted using SSH public key. Then, you use the symmetric key to enrypt your text, and send both the encrypted text and the encrypted key to the recipient.

0

NecroThreading a bit, but I had the same issue and catacomb did not quite cover it, so I ended up making my own variation. Also, I found that dealing with file redirects a bit confusing for my end-users, and the need to download the script beforehand a bit tedious, so my version wraps itself to make an auto-extractible file so the end-user has the easiest time getting the file.

It can be found at https://github.com/BaptisteRichard/rsaCrypt

Please advise that my users are on gitlab and not github so I tweaked that a bit, but it could easily be retrofitted. MR are welcome

-4

Why not do this the super obvious way that doesn't require rolling your own crypto.

Alice sftps to alice@bobserver.com which is setup to only allow public key authentication for the account alice. The properties of ssh nicely ensure that only alice can authemticate. Even a man in the middle attack fails since (assuming you disable ssh1 and insist on the right settings) the initial communication using DH creates a value known to both alice and bob but not to any man in the middle and this can be used to authenticate that no reply or MITM attack can see the contents of the communicatino.

So have alice sftp into your box and download the file.