1
votes

I am new to cryptography so please bear with me! I was wanting to do some asymmetric encryption in Python. I tried using the asymcrypt library but noticed I got a different encryption every time I encrypted a string. I was wondering if there is a way to keep the encryption static (similar to when you hash with sha512, md5, etc.).

To put this into code, basically when I run:

print(encryptData('hello world'))
print(encryptData('hello world'))

I get the following output:

b'\xcf\x93"\x97(\x91\xbd;"\...
b'2\x86L\x0c3\x92W\xec\xaa/...

Ideally what I would want though is:

b'\xcf\x93"\x97(\x91\xbd;"\...
b'\xcf\x93"\x97(\x91\xbd;"\...

Basically, I am looking to:

  • Use a public key to encrypt data and keep that encryption constant as long as the public key is the same.

  • Be able to decrypt data with a private key.

I am looking to have a static encryption because I would want to query a database using these encryptions. Thanks in advance for any help!

1

1 Answers

1
votes

Generally ciphers are expected to produce random output. This is because you can repeat messages, and if the adversary sees identical ciphertext, they can extract information out of that.

For instance, if you have a message consisting of just one bit, 0 or 1, and the attacker knows the plaintext bit of the first encryption (say, 1) then all plaintext can be directly seen from the given ciphertext. In other words, the scheme is not secure for known plaintext. By extension, these schemes are not IND-CCA secure.

The way that a scheme is made secure against known plaintext is to randomize the scheme. For symmetric (block) cipher based schemes this is achieved by supplying an IV or nonce (a unique number), which randomizes the ciphertext when combined with the keyed cipher. For RSA it is achieved by using a random padding. In your case it uses the OAEP padding.


However, you are indicating that this determinism is explicitly what you require, instead of the usual randomization. There are indeed deterministic schemes that do this. There is of course "raw RSA", which means just modular exponentiation. However, that scheme is very insecure, so that's not of much help.

Another way to do this is to use deterministic OAEP or DOAEP. However, the fact that I'm pointing to a paper (by one of the authors of the OAEP scheme, Bellare) should indicate that you're threading outside the safe pathways. A higher up cryptographic library - such as asymcrypt that you're pointing at - won't provide it. It should however be relatively easy to implement it if you already have the source of OAEP (i.e. rather hard, but not as hard as implementing OAEP).

Of course, using deterministic encryption will not make the scheme invulnerable against known plaintext; only randomization can do that.

As an aside, your requirements are also on topic for homomorphic encryption, which often use deterministic encryption as well. That's generally considered a specialist subject though.


One ugly trick is to encrypt (wrap) an AES key once, then use that AES key with a static IV to encrypt data. It is extremely ugly since you'd need to keep the AES key for any encrypting any additional messages. Once wrapped with the public key you need the private key to retrieve the symmetric AES key, and that is only possibly when decrypting.


You can of course also use a hash function, but beware that you may leak information about the plaintext. Bruteforcing the hash of a single bit, as in the example before, will be extremely easy after all, so it is even less secure than deterministic encryption.

If you are using a symmetric key with the hash (e.g. using HMAC) then you're back to the earlier problem with the AES key, so that's not of much help either.