I want to encrypt a file with a private key and decrypt it with a public key. A public key will be embedded in my app. So I want to have a guarantee that the file was created by me. How can I use gpg or openssl to implement it.
Using a private key to attach a tag to a file that guarantees that the file was provided by the holder of the private key is called signing, and the tag is called a signature.
There is one popular cryptosystem (textbook RSA) where a simplified (insecure) algorithm uses has public and private keys of the same type, and decryption is identical to signature and encryption is identical to verification. This is not the case in general: even RSA uses different mechanisms for decryption and signature (resp. encryption and verification) with proper, secure padding modes; and many other algorithms have private and public keys that aren't even the same kind of mathematical objects.
So you want to sign the file. The de facto standard tool for this is GnuPG.
To sign a file with your secret key:
gpg -s /path/to/file
--local-user option to select a secret key if you have several (e.g. your app key vs your personal key).
file.gpg to the place where you want to use the file. Transfer the public key as well (presumably inside the application bundle). To extract the original text and verify the signature, run
If it's more convenient, you can transfer
file itself, and produce a separate signature file which is called a detached signature. To produce the detached signature:
gpg -b /path/to/file
gpg file.gpg file
You can additionally encrypt the file with the
-e option. Of course this means that you need a separate key pair, where the recipient (specified with the
-r option) has the private key and the producer has the public key.
Use OpenSSL to do that. Follow a simple example:
To encrypt a file:
openssl rsautl -encrypt -inkey public_key.pem -pubin -in <decrypted file> -out <encrypted file>
To decrypt a file:
openssl rsautl -decrypt -inkey private_key.pem -in <encrypted file> -out <decrypted file>
You're speaking of an app. That means you probably want to use a library, not a command line. How to do that is out of scope for UNIX & Linux SE (and you didn't even tell us what language your app is written in), but there are several libraries which can do what you want:
- OpenSSL's libcrypto has several primitives to deal with signature verification
- GPGME is a library written by the author's of GnuPG, which allows many things, among them signature verification.
- GnuTLS also exposes its internal cryptographic primitives, however they don't recommend it.
I'm sure there are more, these are just the most popular solutions. Most of these libraries have bindings for other languages, too, in case you're not using C.