What I need to do is this:
at my server: get a file and encrypt
at many remote devices, I need to decrypt the file (don't need to check autenticy/signature)
I can't give the remote devices the hability to encrypt!
What I did -- Step 1 -- key preparation:
at my notebook:
gpg --gen-key
gpg --armor --export KEYNUMBER > key.pub
gpg --armor --export-secret-key KEYNUMBER > key.priv
at my server:
gpg --import < key.pub
at remote devices
gpg --import < key.priv
What I did -- Step 2 -- encrypt the file:
at my server:
gpg --armor --encrypt --recipient KEYNUMBER < file.orig > file.asc
at remote devices
gpg --decrypt < file.asc > file.out
All works OK this way. As I wished.
But, If I do at remote devices "gpg --armor --encrypt --recipient KEYNUMBER < file.orig > file.asc" this generates sucessfully. I don't want the remote device to be able to encrypt. It is supposed only to decrypt.
Any hints about how to solve this?
Thanks,
You cannot prevent the clients being able to encrypt to that key, as the secret key always includes the public key in OpenPGP (which is implemented by GnuPG).
From RFC 4880, highlighting added by me:
5.5.1.3. Secret-Key Packet (Tag 5)
A Secret-Key packet contains all the information that is found in a Public-Key packet, including the public-key material, but also includes the secret-key material after all the public-key fields.
5.5.1.4. Secret-Subkey Packet (Tag 7)
A Secret-Subkey packet (tag 7) is the subkey analog of the Secret Key packet and has exactly the same format.
If you want to make sure a message was sent from the server, you will have to sign it using a second key pair, where the server has the private key and the clients only the public one.
You should ask yourself why you don't want the remote device to be able to encrypt. On the one hand you say that you don't need authentication, but OTOH you probaly want to achieve some kind of authentication by ensuring that only the server is able to encrypt. So if you need authentication and integrity protection, use the mechnisms that are designed for it, namely digital signatures. If you don't need authentication, don't worry about the devices being able to encrypt messages.
Related
I created a PGP public/private key using the following command from my local machine
gpg --full-generate-key --openpgp
I encrypt a file using Golang code(https://github.com/ProtonMail/gopenpgp), and the BouncyCastle Java library decrypts the file(on a different server). Encryption and decryption work when I encrypt the file from my local machine. Decryption fails when I run the same code on my server to encrypt the file. I also noticed that the encrypted file packets differ when I encrypt on my local machine vs. the server. I am using the following command to list packets.
gpg --list-packets ~/encrypted_file_name.pgp
Is it possible to use the public key on the server-generated on my local machine? How to do PGP encryption on a server?
Thanks.
It is probably worth double checking everything outside your code using the gpg cli to rule out weirder issues.
On the encrypting side run:
# list the keys and grab the key id you expect, it should be 40 characters uppercase+numbers
gpg --list-keys
# encrypt a message for that ID
echo 'test' | gpg -ear <KEY_ID>
Copy the output of the above to your clipboard, then on the decrypting server run the following:
# list the secret keys available, there must be one in this list with the exact same KEY_ID from above
gpg --list-secret-keys
# make sure you can use that key by decrypting the message from the first step
cat <<EOF | gpg -d
<paste the message>
EOF
If this works then we'll probably need you to put together code that reproduces the issue.
Only the one who encoded it into or onto a program, etc is able to decode or decrypt it via the certificate as required along with a passphase that would be applied no one can access unless digital signature matches, certificate and passphase.
I have a salt that while decoded is not in an openSSL readable format. The salt is in the DES3 encryption standard and looks something like this Salted__}..O.G....^..GZ LbvbJ5eYm...R...,#.M.U...
I know that this flag is formatted incorrectly since whenever I execute openssl des3 -d -salt -in file.des3 -out file.txt -k <password> it returns bad decrypt. I was wondering how the flag is supposed to be formatted and if outside the dots there are any other characters that dont belong
Thank you
Someone's here for picoCTF... eheheh
In the openssl encryption format, for that cipher, the first 8 bytes are the ascii codes for the string "Salted__" and the next 8 bytes represent the salt...
So if we have the following "Salted__12345678", as the first 16 bytes from the file, the Salt is "12345678"...
But, when trying to decrypt a file using the OpenSSL tool, the tool already knows how to get the salt, and knows the value of the salt, so there's no need for you to get that value, unless you want to use another tool.
(Just a small side-note)
If you're indeed doing the picoCTF, you should use the Webshell for the decryption, because of the version of OpenSSL. For some people it worked...
Hope it answered your question.
I got a HTTP-Post in Wireshark with a encrypted payload.
Where can I add the Key for decrypting the content?
The Content should be JSON and the encryption is AES 128 bit. I got the Key in HEX.
There was no success using several online decryption tools.
Wireshark accepts keys in PEM format. They usually look like this:
-----BEGIN ENCRYPTED PRIVATE KEY-----
Mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END ENCRYPTED PRIVATE KEY-----
To enter the key in Wireshark, you need to go to Edit-> Preferences -> Protocols -> SSL
Note that the ability of any tool to decipher the encrypted stream depends on the key-exchange mechanism. If the client and server use, for example, a variation of the Diffie-Hellman algorithm for key exchange, it would be impossible to decrypt the stream.
When I want to encrypt large files, I have found the following command:
openssl smime -encrypt -binary -aes-256-cbc \
-in large_file.img -out large_file.img.dat \
-outform DER \
public-rsa2048.pem
The private/public keys have been created like this:
openssl req -x509 -nodes -newkey rsa:2048 \
-keyout private-rsa2048.pem -out public-rsa2048.pem
So I am using aes-256-cbs as well as an rsa-key.
Which one is now responsible for the encrpytion?
Which one does impact the performance and how?
If I increase/lower the public key (rsa512 vs rsa4096), does this impact the performance?
If I choose a different aes algorithm, does this impact the performance as well?
Could someone bring some light into this matter please?
Are there any other methods to encrypt large files?
Using the openssl smime command to encrypt data encrypts it in such a way that it can be received and decrypted by a recipient using email. This means that it uses certificates representing various entities (sender, recipient) and containing keys uniquely associated with those entities to both sign, encrypt, decrypt, and verify signatures on the contained data.
As Artjom pointed out in their comment, a hybrid cryptosystem is used. This means a combination of symmetric and asymmetric encryption algorithms are used, as each has benefits and drawbacks. Symmetric encryption (such as AES) is extremely fast in comparison to asymmetric encryption (such as RSA). However, AES/CBC provides only confidentiality, not integrity, authentication, or non-repudiation. Asymmetric encryption can provide integrity, authentication, and non-repudiation. Asymmetric encryption also has fairly low limits for the amount of data it can encrypt (for example, an RSA-4096 bit key can encrypt at most 446 bytes at once). By combining both methods, we can exercise each for their strengths and mitigate the weaknesses of the other.
In this case, let our message be M. An AES/CBC key Kaes of length 256 bits is generated and used to encrypt the raw data such that the cipher text C is C = E(Kaes, M). The recipient's public key Krpub is then used to encrypt Kaes as C' = E(Krpub, Kaes). The cost of encrypting this small amount of data is relatively low, even though we are using an expensive operation.
Note prior to encrypting the ephemeral session key, it is likely signed using the sender's private key Kspriv unless digital signing is disabled. I am not 100% certain with S/MIME, but this is how PGP works, as when sending to multiple recipients, it would be much more expensive to encrypt the session key with n recipient's public keys and then sign each encrypted key with the sender's private key O(2n) vs. O(n+1) (not really Big-O notation, but effective for communicating the point). The signature of the session key is the same regardless of recipient because it depends only on the sender's private key.
Now all that is left is to concatenate the encrypted session key C' and the cipher text C and transmit them to the recipient. In a real S/MIME message, the identifying information about the sender's public key is transmitted as well in order to facilitate signature verification. The recipient parses the complete encrypted message, decrypts the session key using the recipient's private key Krpriv and then uses the session key Kaes to decrypt the cipher text C.
However, it seems like all of this may be overkill for your situation. If you do not need to integrate with an email communication system and are simply trying to encrypt large files for storage, openssl also offers a simple enc command. You can use it as follows:
Password-based encryption:
$ openssl enc -aes-256-cbc -in large_plain_file.dmg -out large_encrypted_file.enc -k thisIsABadPassword
-k allows you to enter a password on the command line from which the key will be derived. OpenSSL uses a deterministic key derivation function (KDF) (effectively key, iv = MD5(password||salt)). You can run this command with -p on the end to get the key, salt, and IV printed to the console. The IV is deterministically derived from the password and salt. A KDF like PBKDF2 is recommended but the library function in OpenSSL does not expose it to the command-line tool for some reason.
Warning you can run this and specify -nosalt to skip the salt generation, but this is not recommended as it makes an already extremely weak KDF even weaker.
Keyed encryption:
$ openssl enc -aes-256-cbc -in large_plain_file.dmg -out large_encrypted_file.enc K 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210 -IV 0123456789ABCDEFFEDCBA9876543210
Running with the actual key and IV provided. The key is 32 bytes (256 bits) and the IV is 16 bytes (the size of one AES block).
To decrypt the data, run the command with the -d flag:
$openssl enc -aes-256-cbc -d -in large_encrypted_file.dmg -out large_decrypted_file.enc
This is going to be simpler for you (no certificates/key pairs needed) and faster (no RSA encryption).
Something to keep in mind for all of this is that the password/key will be kept in terminal history if you provide it in the command invocation. Running without -k or -K will prompt the password to be entered in a secure prompt. Or use -pass to read from an environment variable, file, or file descriptor.
Update to address original questions explicitly:
The AES key is responsible for encrypting the data. The RSA key is used to encrypt the AES key.
Both impact the performance. The AES key is encrypting much more data, but is much faster than RSA encryption.
Yes, changing the size of the RSA key impacts performance, (higher key sizes are slower), but for a large file this is unlikely to be the limiting factor on performance.
Yes, changing the AES mode of operation may have a substantial impact on performance. AES/CBC, AES/OFB, and AES/CFB are similar in that they are serial operations (depending on the result of one block operation to proceed to the next), but AES/CTR operates as a stream cipher and can be parallelized to provide both encryption and decryption.
See answer above.
Is there a very primitive method or protocol to send messages from two machines not on the same local network? I don't know what is available, but is there a terminal or prompt method for sending plaintext messages over the internet? Is it simple enough to code it from scratch?
Can I send a simple plaintext message from one machine to the next (if I have that machine's information) and then toy around with adding encryption and other crytopgraphy methods as an exercise?
You need netcat or sometimes called nc. It is on most Linux distros and OSX and available for Windows too.
Examples available here.
Documentation here.
On a server, run
$ nc -l 2389 > receivedfile
to listen on port 2389 and write whatever it receives to file "test"
And on the client, send a file to that port
cat yourfile | nc localhost 2389
or send a message
echo Hello | nc localhost 2389
Once you have got straightforward file transfer working, you can send an encrypted file like this:
openssl enc -aes-256-cbc -salt -in yourfile | nc localhost 2389
It sounds like telnet will do the job you're looking for. It's the most primitive protocol I can think of for this use case.
All data octets except 0377 are transmitted over the TCP transport as is. Therefore, a Telnet client application may also be used to establish an interactive raw TCP session[.]