Background:
- Some existing programs, such as git-annex (git-annex encryption) and pass, delegate cryptography to GPG, "a complete and free implementation of the OpenPGP standard". More specifically, these programs rely on GPG key id-s as a way to interact with GPG:
GPG is used to create and manage GPG public/private key pairs.
The program is instructed to use a specific GPG public/private key pair via its key id.
While relying on GPG is good and commendable, the specific way in which this is being done (via GPG key id-s) leads to an arguably unnecessary use of public key cryptography under the hood.
Public key/asymmetric cryptography addresses some specific use cases that, broadly speaking, involve the secure transfer of information between one trusted and multiple untrusted parties. If somebody decides to use
passto store their own passwords in a public git repository, there is no untrusted party in this scheme to justify the use of asymmetric cryptography.Traditional/symmetric cryptography is potentially more secure than asymmetric cryptography. E.g., there exist quantum algorithms that break asymmetric cryptography, but there do not exist quantum computers to run them- yet. While such developments are not guaranteed, no similar (potential) weaknesses are known for symmetric cryptography.
Asymmetric cryptography benefits from 2 distinct layers of security:
(a) the private key is symmetrically encrypted with a passphrase
(b) the (encrypted) private key is kept in a secure location
Thus, e.g., (a) adds nothing to the security of asymmetric cryptography as long as (b) holds. It is perfectly valid (though unadvisable) to do asymmetric cryptography with an empty passphrase.
Normal symmetric cryptography, with a single private key, only provides security of type (a). If one were to replace asymmetric with symmetric cryptography, it would be nice to keep both security levels (a) and (b). One way to do that is with 2 symmetric levels:
generate private random string
symmetrically encrypt private random string using passphrase, store privately
symmetrically encrypt message with private random string, store publicly
- The following describes what happens under the hood when a program like
passuses GPG via a GPG key id. (Assume public key cryptography is RSA and symmetric cryptography is AES.) First, GPG is used to:
(i) create an RSA public/private key pair
(ii) RSA public key is unencrypted, store privately (hard drive) or publicly (key server)
(iii) AES-encrypt RSA private key with passphrase, store privately
Next, following OpenPGP encryption, this is how encryption works:
(iv) generate random session key
(v) AES-encrypt message with session key, store publicly
(vi) RSA-encrypt session key with RSA public key, store publicly
Observe that the message is compromised by breaking either (v) or (vi).
Unnecessary Potential Vulnerability:
Suppose that in the future quantum computers are developed, and RSA is broken. (For the paranoid, suppose RSA is already broken.) While this will bring in changes to how we do things like online banking, it will also have a completely unnecessary negative impact on the security of the data created by pass/git-annex.
Just how bad this is depends on whether the RSA public key from (ii) above is stored publicly or privately. If it's stored publicly, the data is already compromised: an attacker can decrypt (vi) obtaining the session key, then decrypt (v) with the session key to get the message. If the RSA public key from (ii) is actually kept private, the security of the data is reduced to (b), the security of the medium holding the RSA public key, which is equivalent to doing asymmetric encryption without a passphrase.
This vulnerability, far fetched or not, is completely unnecessary, as it is due to the unnecessary use of public key cryptography inherent in the existing interface between programs like pass/git-annex and GPG (via GPG key id-s).
Question:
Is there a "relatively easy" way to:
remove the use of asymmetric encryption when GPG is used under the hood through GPG key id-s
continue to use GPG to manage keys as before
maintain the 2-level security mentioned in 4 as (a) and (b)
The complete schematic I'm after is:
(i') generate private random string
(ii') AES-encrypt private random string with passphrase, store privately
(iii') AES-encrypt message with private random string, store publicly
I understand how to do each of these steps separately, but what I'm asking about is the best way to plug such a "fix" in the way programs might use GPG via GPG key id-s. Specifically, I expect such programs to issue external calls of the form gpg --encrypt --recipient <keyid> and gpg --decrypt.
Conclusion: It seems that there is no magic bullet, and intercepting these calls by using a gpg wrapper script is the only way to go. Perhaps GPG should consider this issue in the future.