SaltStack: RSA e = d = 1
An instance of textbook RSA has three parameters: e, d, and n, where e = d-1 (mod phi(n)). Encryption of a message m is me, and decryption of a ciphertext c is cd = (me)d = med = m1 = m.
When you set e = 1, encrypting a message does not change it, since raising any number to the power of 1 does not change it. SaltStack was using 1 as their RSA public key (e), so encryption was doing nothing:
@@ -47,7 +47,7 @@ def gen_keys(keydir, keyname, keysize, user=None):
priv = '{0}.pem'.format(base)
pub = '{0}.pub'.format(base)
- gen = RSA.gen_key(keysize, 1, callback=lambda x, y, z: None)
+ gen = RSA.gen_key(keysize, 65537, callback=lambda x, y, z: None)
cumask = os.umask(191)
gen.save_key(priv, None)
os.umask(cumask)
What really amazes me is that the library they’re using, M2Crypto, lets you do this without any kind of error or warning.
Lessons Learned:
- Have a professional cryptographer review your parameter choices.
- Write unit tests to check that messages can’t be decrypted with a different key (edit: This might not catch the problem, see the comments).
- Before using a cryptography library, it’s a necessary to understand something about what it’s doing behind the scenes.
