-1

For a Crypto class we've been given a DESede ciphertext using ECB with no padding => "6t8Z5bKl5ybJL+MiFerNBmiTDS7wlTEUdWNwJJApWmQ==" which is in base64 form. We were given clues about the key and so I constructed all possible keys (where all are in an ASCII format).

            String strToDecrypt="6t8Z5bKl5ybJL+MiFerNBmiTDS7wlTEUdWNwJJApWmQ==";
            byte[] input = strToDecrypt.getBytes();

            //Decrypt
            Cipher b = Cipher.getInstance("DESede/ECB/NoPadding");
            b.init(Cipher.DECRYPT_MODE, keySpec);
            byte output[] = b.doFinal(input);
            String out = new String(output);
            System.out.println(new String(out));

When I run this code using my keys, I get an IllegalBlockSizeException as my input isn't a multiple of 8 bytes. I'm confused as to which "bases" to use. As I've said above, the ciphertext is in base64 so When running Cipher.DECRYPT should I be giving keys in a certain "base" or the string I want to decrypt in a certain base.

  • 3
    `getBytes()` doesn't know your string is supposed to be Base64 encoded. You need to [decode the string as Base64](https://stackoverflow.com/questions/469695/decode-base64-data-in-java) instead of just calling `getBytes()`. – Blorgbeard Oct 13 '17 at 22:15
  • 2
    More explicitly, `byte[] input = Base64.getDecoder().decode(strToDecrypt);` – erickson Oct 13 '17 at 22:19
  • @erickson thanks for that. That gave me an error but using getMimeDecoder().decode(strToDecrypt) worked instead. All my outputs are like "9�����f8�uK��=�#�����g9S33." with no plaintext in any position. All my keys are in ASCII in the form "Êþº¾ÿÿÿÿÊþº¾ÿÿÿÿÊþº¾ÿÿÿÿ". Any suggestions on what I'm doing wrong? –  Oct 13 '17 at 22:28
  • 3
    One bit wrong in the key will yield complete garbage in the plain text. My best guess would be that you haven't found the right key. I don't understand your comment, "All my keys are in ASCII in the form '...'." That's not ASCII. Did you instructor tell you how to recognize correctly decrypted plain text? – erickson Oct 13 '17 at 22:33
  • @erickson well we were give a hex template where our keys look something like this "XY:XY+1:XY+2:XY+3:XY+4:XY+5:FF:FF" where XY is an unknown byte i.e it could be 11110001 so XY+1 would be 11110010. So once I calculated all possiblities of byte keys, I converted the bytes with an ASCII converter to the above. And he said it will just be plain English so I've been parsing some common words etc. and nothing –  Oct 14 '17 at 00:03
  • 1. DESede is Triple DES and takes a 24-byte key. 2. The lest swignificant bit in each key byte is ignored. 3. DES had a block size of 8 bytes so the inpout must be a multiple of 8 bytes–or paddimg must be added. 4. When you have a sting like "9�����f8�uK��=�#�����g9S33, not characters. The "�" symbol means the byte is a value that does not have a displayable character. – zaph Oct 14 '17 at 00:28
  • DES uses an 8-byte key. Your base-64 encoded ciphertext is invalid. Its padding is inconsistent with its length. Either your instructor messed up, or you added an '=' to the end, or deleted some characters in the middle, or some combination of those. As I said before, a one bit mistake will yield garbage when you decrypt. Explain why the input is not valid. – erickson Oct 14 '17 at 00:39
  • @erickson The question states "DESede" which is Triple DES and takes a 24-byte key. While there is a two key version a one key version makes no sense for ede. – zaph Oct 14 '17 at 23:23
  • Possible duplicate of [Tips on using 3DES correctly](https://stackoverflow.com/questions/46758743/tips-on-using-3des-correctly) – zaph Oct 15 '17 at 19:19
  • 1
    Next time, start with complete and accurate statement of problem. If you need to add information, edit the question; don't ask the same question multiple times. – erickson Oct 16 '17 at 04:04

1 Answers1

1

Don't make the key generation harder than it needs to be. You want to try each possible value for the first byte of the variable section. But what if that value is 0xFB? Subsequent values would be 0xFC, 0xFD, 0xFE, and 0xFF. But what about the last value? You can assume that they wrap around, to 0x00.

If that's the case, something like this should work to find the correct key:

static byte[] search(byte[] ciphertext) throws GeneralSecurityException {
  byte[] key = template(); /* Initialize the fixed bytes of "key" */
  Cipher nopadding = ... ; /* Create the correct cipher */
  for (long xy = 0; xy < 256; ++xy) { /* Iterate over possible values */
    for (long wz = 0; wz < 256; ++wz) { /* Is there another range? */
      for (int off = 0; off < 6; ++off) {
        key[8 + off] = (byte) (xy + off); /* Set the first range */
      }
      for (int off = 0; off < 6; ++off) {
        key[16 + off] = (byte) (wz + off); /* Set the second range */
      }
      nopadding.init(/* Initialize the cipher with your key */);
      byte[] plaintext = nopadding.doFinal(ciphertext);
      String str = new String(plaintext, StandardCharsets.US_ASCII);
      /* Return the key if it produced valid text */
      if (str.indexOf('\uFFFD') < 0) return key;
    }
  }
  throw new IllegalArgumentException(); /* No key found */
}
erickson
  • 265,237
  • 58
  • 395
  • 493