8 Replies Latest reply on Aug 26, 2011 6:37 AM by safarmer

# Repeatable encryption with RSA public key cipher

Hello,

I have the following problem: I try to encrypt a byte array with a RSA public key cipher and want to get the same encrypted byte-array for every invocation of doFinal().

Purpose*
Two people (a and b) maybe share the same secret. Yet they do not trust each other until they have confirmed that they share the same secret. To check if both share the same secret the following protocol shall be applied (over an unsecure communication channel using person c which they do not trust either). There is also no other person that may assist in establishing trust (i.e. building chains of trust).

(1) a generates RSA public / private key
(2) a encrypts her secret with the RSA public key
(3) a sends the encrypted secret with her RSA public key to b
(4) b uses the RSA public key of a to encrypt his secret
(5) if the encrypted secret of a matches the encrypted secret of b, then do (6), otherwise a and b do not share the same secret, thus they stop conversatzion
(6) b generates his own RSA public / private key
(7) b encrypts the (unencrypted) secret with his private key
(8) b encrypts his secret (encrypted with his private key), as well as his public key, with the public key of a
(9) b sends his secret (encrypted with his private key) and his public key to a
(10) a decrypts the secret and public key of b with her private key
(11) a decrypts the secret with the public key of b
(12) a double-checks if the secret received from b acually meets the one a knows => trust established, finish

So, what I want to achieve is that the following code prints "true":
byte[] potentialSecret = new byte[]{1, 2, 3, 4, 5};
KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
kpg.initialize(512);
KeyPair kp = kpg.generateKeyPair();
PublicKey key = kp.getPublic();
Cipher c = Cipher.getInstance(RSA);
c.init(Cipher.ENCRYPT_MODE, key);
System.out.println(Arrays.equals(c.doFinal(xy), c.doFinal(xy)));
I tried to "mess around" with initialization vectors but always ended with exceptions of various kind.

Thank you very much
Bjoern

PS: btw, how do I markup code? This is my first posting in Oracle forums.
• ###### 1. Re: Repeatable encryption with RSA public key cipher
Hi,

Why not just exchange public keys and use them to encrypt the secret then send the encrypted secret to the other party. Then decrypt with the private key. This still doesn't imply trust as this scheme (along with the one you propose) is vulnerable to a man in the middle attack. An attacker would just need to intercept the key and perform the operations pretending to be the other parties involved. This just gives you secure communication with the other end, but you do not know who the other end is.

Cheers,
Shane
• ###### 2. Re: Repeatable encryption with RSA public key cipher
byte[] potentialSecret = new byte[]{1, 2, 3, 4, 5};
KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
kpg.initialize(512);
KeyPair kp = kpg.generateKeyPair();
PublicKey key = kp.getPublic();
Cipher c = Cipher.getInstance(RSA);
c.init(Cipher.ENCRYPT_MODE, key);
System.out.println(Arrays.equals(c.doFinal(xy), c.doFinal(xy)));
Use
tags to mark up your tags (one either side of the code)

Cheers,
Shane
• ###### 3. Re: Repeatable encryption with RSA public key cipher
Hi safarmer,

I thought of this "traditional" pki-scenario. Yet, your proposed scheme is vulnerable to man-in-the-middle attack. If a asks b for his public key, c might reply with his public key. This would result in the situation that a encrypts her secret with the public key of c, meaning that c might get knowledge of the secret.

In my scheme, even c intercepts any message, he cannot identify to a neither b that c knows the secret. First of all, with the information provided by a, it is not possible to reconstruct the secret. Only b, who might know the secret can repeat the steps of a to check if a actually knows the secret. If b knows the same secret as a, he uses "traditional" public / private key encryption to exchange keys and identify to a that b knows the secret. As b encrypts his information (the secret as well as his public key) with the public key of a, only a can decrypt this information, leaving c no option to get knowledge of (1) the secret and (2) the public key of b.

If c knows the secret, then he might act as b. But this is fine for me, because a just wants to establish any secure communication with anyone who knows a's secret. There is no need to identify who one really is. Thus, the man-in-the-middle attack is only possible where the man-in-the-middle knows the secret.

PS: thanks for the
.
• ###### 4. Re: Repeatable encryption with RSA public key cipher
If both secrets are the same you could use symmetric encryption to perform a mutual authenticate. You would use the secret as a key to a cipher. You could then exchange a nonce from each client (random number) and calculate enc(nonce 1 || nonce2) on each side exchange results. If the results match they are using the same sequence. I have simplified this but you may get the idea.

The problem with RSA is the padding. You are either using PKCS1 or OAEP witch both use random numbers to make the result different each time. You could use RSA with no padding but then you are open to replay attacks.

Cheers,
Shane
• ###### 5. Re: Repeatable encryption with RSA public key cipher
Hi safarmer,

thank you for the explanation. As the secret can be as short as 8 bit, I hesitate to use it as password to a secret key and then just use the secret key. Further, b might know several secrets, thus he has to probe the secrets he knows against the secret received by a.

Yet, your proposal of using no padding sounds interesting. Particularly, because reply attacks won't matter - I think. If c would replay the message from a, he might get an answer from b, but because c does not know the private key of a, he cannot decrypt the response from b because it is encrypted with a's public key. I hope I do not have an error in my thinking.

What would be the security impact of not using padding? I read several things about it but not fully understood it. One the other hand, as a and b know the length of the secret, I could also use a '0' padding by myself.

What do you think?
• ###### 6. Re: Repeatable encryption with RSA public key cipher
If your security is based on a secret that may be 8bits then you only have 8bits of security. An attacker could send a request with their own key pair with any data. The other party would send back the key and cipher text and then after less than 256 RSA encryption operations you have the secret (if it is 1 byte). You can then resend the request with the correct secret.

Cheers,
Shane
• ###### 7. Re: Repeatable encryption with RSA public key cipher
Hi Shane,

of course, you are right. I think I will set the "no padding" and build some padding on myself, based on the knowledge of the secret they might have in common. It is not really "hard", but I think it will be sufficient.
• ###### 8. Re: Repeatable encryption with RSA public key cipher
If you are building enough data to make the padding more secure you could use the same technique to make a longer secret for a symmetric key as well. You could look at KDF1 and friends. Either way, if your process is discovered, it is just as insecure. This is still security by obscurity.

Cheers,
Shane