I have a tool that takes an RSA public key (e.g. OpenSSL PEM format key), encrypts a message to that public key, then returns the encrypted message. I'm going to be sent a PGP public key and need to pass this to the tool that accepts an RSA public key then return the encrypted data back to the person that sent the PGP key so that they can decrypt it with PGP.

The closest question I've found is "How can I perform PGP encryption and decryption method using openssl commands" and while that's not exactly what I'm looking for, it does provide a partial solution. However, I'm looking for a bit more, specifically in how to convert to/from the two formats.

How can I go about taking a PGP key, extracting the public RSA key from it, converting it to a PEM format, then taking the encrypted data and putting it back into a PGP understandable format?


Converting the key with OpenSSL is not very easy; you'll have to code all the PGP parsing yourself, see RFC 4880. Once you have the n and e values as byte arrays, you can put them in bignums, then in an RSA structure, and then call PEM_write[_bio]_RSA_PUBKEY. Personally I would instead do it in Java using BouncyCastle, which directly supports both PGP keys and data in the bcpg jar and OpenSSL keys (and some data) in the bcpkix jar.

Converting the data is probably impossible. First, it is very unlikely that 'a message' is simply encrypted with RSA -- RSA is only suitable for limited size data, currently about 200 bytes, and that usually isn't enough for the data people want (other than 'twits'). In practice, systems and applications almost always use 'hybrid' encryption -- the data is encrypted using a 'symmetric' (classical, secret-key) algorithm such as AES with a nonce key, and the nonce key is encrypted using the 'asymmetric' (public-key) RSA algorithm. There are several different ways of doing the RSA encryption, and dozens to hundreds of different ways (mostly 'modes') of doing the symmetric encryption. You need to find out exactly what kind of encryption the 'tool' is doing.

PGP, for the (usual) to-recipient-pubkey case, uses what was originally PKCS1 'block type 02' encryption, nowadays retronymed RSAES-PKCS1-v1_5, combined with one of several symmetric algorithms (some common but some not) in a variant of CFB mode that no one else uses at all (very few other things this century use any kind of CFB). The PGP recipient may be able to accept only a subset of the symmetric algorithms, and if so this is expressed in the PGP key block, which the sender is supposed to read and honor, but the public-key format used by OpenSSL, which is the SubjectPublicKeyInfo structure from X.509/PKIX, cannot represent this information. (An X.509/PKIX certificate, which OpenSSL also supports and most well-designed OpenSSL software uses, could represent this information, but in a very different form than PGP.)

Also, PGP's CFB variant is non-authenticating. Back in 1990 it wasn't realized this was a vulnerability, but now it is, so many recipients require or at least prefer using the PGP option to authenticate, which is what other people now call a Message Authentication Code but PGP called a Modification Detection Code. PGP's MDC scheme is not the same as any MAC scheme used by anything else.

Thus in short, unless the 'tool' was designed to do PGP encryption, its output cannot be 'converted' into PGP except by decrypting and re-encrypting it. And if it was designed by a sane person to do PGP encryption, it would aleady accept a PGP publickey. However, since there's no way the tool can determine whether a 'SPKI' publickey as above actually belongs to the intended recipient, you could generate your own keypair, give the tool your publickey, receive the data encrypted using your key and decrypt it, and then re-encrypt in PGP-compatible format using the actual recipient key and an algorithm (and MDC option) matching that key.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.