This discussion is archived
1 Reply Latest reply: Aug 18, 2011 3:04 PM by 800207 RSS

AES/CFB/NoPadding  encryption - can be decrypt by xor

883162 Newbie
Currently Being Moderated
Hi,
Seems like a password can be discovered based on the encrypted value of a former known password (when using the same key).

E.g.
In case I have a clear password: AAA
and I have the enrypted password as bytes :crypt(AAA).

I can decrypt any other password based on the Xor result of the clear & encrypted password : (AAA xor crypt(AAA))
BBB = crypt(BBB) xor (AAA xor crypt(AAA))
Looks like a security problem.
Is this a java bug or mine?
BTW when using AES/CFB8/NoPadding , this is not happening.

Here is the Code Example:
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class MyTest
{
     static SecretKey m_secretKey = null;

     public static void main(String[] args)
     {
          try
          {
               MyTest test = new MyTest();
               test.init();
               test.encrypttionBreak();
          }
          catch (Exception e)
          {
               e.printStackTrace();
          }

     }

     private void init() throws Exception
     {
          if (m_secretKey == null)
               m_secretKey = KeyGenerator.getInstance("AES").generateKey();
     }



     private byte[] aesEncrypt(byte[] data, int mode) throws Exception
     {
          byte[] m_iv = new byte[16];

          for (int i = 0; i < m_iv.length; i++)
          {
               m_iv[i] = (byte) i;
          }

          IvParameterSpec iv = new IvParameterSpec(m_iv);
          Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding", "SunJCE");
          cipher.init(mode, m_secretKey, iv);

          byte[] cipherInput = cipher.doFinal(data);

          return cipherInput;
     }

     public void encrypttionBreak() throws Exception
     {
          String clearText = "aaaaaaaaaaaa";
          byte[] cipherBytes = aesEncrypt(clearText.getBytes(),
               Cipher.ENCRYPT_MODE);

          byte clearBytes[] = clearText.getBytes();
          byte xorKey[] = new byte[clearBytes.length];
          for (int i = 0; i < xorKey.length; i++)
          {
               xorKey[i] = (byte) (clearBytes[i] ^ cipherBytes);
          }

          String password = "mypass";

          byte[] passwordEncrypted = aesEncrypt(password.getBytes(),
               Cipher.ENCRYPT_MODE);

          byte breakFinal[] = new byte[passwordEncrypted.length];
          for (int i = 0; i < breakFinal.length; i++)
          {
               breakFinal[i] = (byte) (passwordEncrypted[i] ^ xorKey[i]);
          }

          System.out.println("break final " + new String(breakFinal));

     }

}


Edited by: sabre150 on 19-Aug-2011 02:37

Moderator: added [ code] tags to make the code readable.
  • 1. Re: AES/CFB/NoPadding  encryption - can be decrypt by xor
    800207 Newbie
    Currently Being Moderated
    It is your bug, because you are randomly picking a mode and method without really understanding them. Just look at the definition of [https://secure.wikimedia.org/wikipedia/en/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29]

    Now look at what your "crypt" function does. You use a fixed iv for everything, we'll just label it IV.So crypt('AAA') = AES(key, iv) xor 'AAA'. Therefore crypt('AAA') xor 'AAA' = AES(key, iv). You should be able to figure out what crypt('BBB") xor crypt('AAA') xor 'AAA' does.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points