Why is AES / CTR / NoPadding broken?

To keep it simple, I now use a hard-coded key and IV. AesWriter (below) encrypts and writes the source text,, Abc\t1234\t\t\t\t\nto a file as 11,87,-74,122,-127,48,-118,39,82,-83,68,-30,-84. But AesReader (also below) decrypts the contents of the file sequentially zW?D?4?rc?~???~?_=p?J. Any ideas I'm wrong about?

public class AesWriter extends Activity {
    ...
    private void writeConfig() {
        ...
        try {
            Cipher cipher = Cipher.getInstance(AesReader.AES_ALGORITHM, 
                    AesReader.PROVIDER);
            cipher.init(Cipher.ENCRYPT_MODE, AesReader.getSecretKeySpec(),
                    AesReader.getIvParameterSpec()); 
            byte[] encrypted = cipher.doFinal(config.getBytes());
            OutputStreamWriter out =
                new OutputStreamWriter(openFileOutput(fileName, 0));
            out.write(AesReader.asHex(encrypted));
            out.close();
            ...

public class AesReader extends Activity {
    public static final String AES_ALGORITHM = "AES/CTR/NoPadding";
    public static final String PROVIDER = "BC"; 
    private static final byte[] aesKey128 = { // Hard coded for now
        78, -90, 42, 70, -5, 20, -114, 103, 
        -99, -25, 76, 95, -85, 94, 57, 54};
    private static final byte[] ivBytes = { // Hard coded for now
        -85, -67, -5, 88, 28, 49, 49, 85, 
        114, 83, -40, 119, -65, 91, 76, 108};
    private static final SecretKeySpec secretKeySpec = 
        new SecretKeySpec(aesKey128, "AES");
    private static final IvParameterSpec ivSpec = 
        new IvParameterSpec(ivBytes);
        ...
    private void readConfig() {
        String fileName = configuration.getFileName();
        try {
            InputStream is = openFileInput(fileName);
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM, PROVIDER);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
            CipherInputStream cis = new CipherInputStream(is, cipher);
            InputStreamReader isr = new InputStreamReader(cis);
            BufferedReader reader = new BufferedReader(isr);
            String s;
            while ((s = reader.readLine()) != null) {
                configuration.modify(s);
            }
            is.close();
            ...
    public static SecretKeySpec getSecretKeySpec() {
        return secretKeySpec;
    }
    public static IvParameterSpec getIvParameterSpec() {
        return ivSpec;
    }
    public static String asHex(byte buf[]) {
        StringBuffer strbuf = new StringBuffer(buf.length * 2);
        int i;
        for (i = 0; i < buf.length; i++) {
            if (((int) buf[i] & 0xff) < 0x10) {
                strbuf.append("0");
            }
            strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
        }

        return strbuf.toString();
    }

Working code based on erickson's suggestion:

public class FileIO {
    public final static String EOL = "\n";
    public static final String AES_ALGORITHM = "AES/CTR/NoPadding";
    public static final String PROVIDER = "BC"; 
    private static final byte[] AES_KEY_128 = { // Hard coded for now
        78, -90, 42, 70, -5, 20, -114, 103, 
        -99, -25, 76, 95, -85, 94, 57, 54};
    private static final byte[] IV = { // Hard coded for now
        -85, -67, -5, 88, 28, 49, 49, 85, 
        114, 83, -40, 119, -65, 91, 76, 108};
    private static final SecretKeySpec secretKeySpec = 
        new SecretKeySpec(AES_KEY_128, "AES");
    private static final IvParameterSpec ivSpec = 
        new IvParameterSpec(IV);

    public String readAesFile(Context c, String fileName) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            InputStream is = c.openFileInput(fileName);
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM, PROVIDER);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
            CipherInputStream cis = new CipherInputStream(is, cipher);
            InputStreamReader isr = new InputStreamReader(cis);
            BufferedReader reader = new BufferedReader(isr);
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line).append(EOL);
            }
            is.close();
        } catch (java.io.FileNotFoundException e) {
            // OK, file probably not created yet
            Log.i(this.getClass().toString(), e.getMessage(), e);
        } catch (Exception e) {
            Log.e(this.getClass().toString(), e.getMessage(), e);
        }
        return stringBuilder.toString();
    }

    public void writeAesFile(Context c, String fileName, String theFile) {
        try {
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM, PROVIDER); 
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
            byte[] encrypted = cipher.doFinal(theFile.getBytes()); 
            OutputStream os = c.openFileOutput(fileName, 0);
            os.write(encrypted);
            os.flush();
            os.close();
        } catch (Exception e) {
            Log.e(this.getClass().toString(), e.getMessage(), e);
        }
    }
}
+3
source share
1 answer

The full code is not displayed, but it looks like you are writing hexadecimal text to the file, but you are reading it without decoding back to bytes. Skip the hexadecimal encoding (I assume this should have helped you debug).

+3
source

Source: https://habr.com/ru/post/1764049/


All Articles