I can't decrypt AES

My colleague encrypts data using AES-256 without a vector using the node module.js aes-js. Accordingly, the key is a 32-dimensional array, and the encrypted string is a string.

In Java Android, I'm trying to do something like

 public static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    byte[] decrypted = cipher.doFinal(encrypted);
    return decrypted;
}

But I always get an error -

javax.crypto.IllegalBlockSizeException: last block incomplete in decryption

But in the TextView I drive in this way

  byte[] key = new byte[]{83, 63, (byte) 180, (byte) 178, (byte) 169, 38, 21, 10, 62, (byte) 160, (byte) 216, (byte) 191, 122, 13, 55, 68, (byte) 181, 4, (byte) 180, 20, 8, 117, (byte) 138, 36, 51, 26, 7, 90, 3, (byte) 184, 47, 17};

    TextView t = findViewById(R.id.text);
    try {
        t.setText(Decrypt.decrypt(key, "cc1e55b3a5c6fbcc22c67bcafbb2e2704e25c9db8959f4a9d6570666d73fb15c49139b".getBytes()).toString());
    } catch (GeneralSecurityException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }

This is how a colleague encrypts and decrypts at home

let encrypt = function(text, key){    
if(!key){
    key = KEY;
}
let encryptionBlock = new aes.ModeOfOperation.ctr(key, new aes.Counter(100));
return aes.utils.hex.fromBytes(encryptionBlock.encrypt(aes.utils.utf8.toBytes(text)))
}

And decryption

let decrypt = function(text, key){    
if(!key){
    key = KEY;
}
let encryptionBlock = new aes.ModeOfOperation.ctr(key, new aes.Counter(100));
return aes.utils.utf8.fromBytes(encryptionBlock.decrypt(aes.utils.hex.toBytes(text)))
}

How do I decipher this text? I have already tried many ways. Thank you in advance

Author: Ker_ Jen, 2017-11-24

2 answers

At least 2 things you are doing wrong:

  1. "...".getBytes(). Encrypted data is binary data, not a string. You should get the bytes from the hex string, not the bytes from the characters.
  2. Even if you do the first one correctly, you have an encrypted message length of 35 bytes. In AES, it must be a multiple of the block size, i.e. 16 bytes. So Java throws an exception.

I do not know how your encrypted message was received, but it is definitely not received a standard AES application. So I can't tell you how to decipher it.

After updating the question.

In the case of CTR, you need to do this:

byte[] ciphertext = new byte[] { 113, (byte)202, 74, (byte)141, 19 };
byte[] key = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
byte[] counter = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100 };
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
IvParameterSpec ctrParameter = new IvParameterSpec(counter);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ctrParameter);
byte[] plain = cipher.doFinal(ciphertext);
System.out.println(new String(plain, StandardCharsets.UTF_8));

Outputs hello. Note the counter array. The last byte is 100, which corresponds to the counter specified in the nodejs code.

I can also add that using the same counter with the same key is a very large security hole, an attacker will be able to decrypt the message even without knowing the key.

 2
Author: Zergatul, 2017-11-25 15:31:44

Try this:

public static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
    final byte[] bt = new byte[16];
    Arrays.fill(bt, (byte)0); 
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, bt);
    return cipher.doFinal(encrypted);
}
 0
Author: And, 2017-11-25 11:01:52