简体   繁体   English

为什么AES / CTR / NoPadding坏了?

[英]Why is AES/CTR/NoPadding broken?

To keep it simple I am using a hard coded key and IV for now. 为了简单起见,我现在使用硬编码密钥和IV。 AesWriter (below) encrypts and writes the original plaintext, Abc\\t1234\\t\\t\\t\\t\\n , to a file as 11,87,-74,122,-127,48,-118,39,82,-83,68,-30,-84 . AesWriter(下面)将原始明文Abc\\t1234\\t\\t\\t\\t\\n加密并写入文件11,87,-74,122,-127,48,-118,39,82,-83,68,-30,-84 But AesReader (also below) decrypts the contents of the file consistently as zW?D?4?rc?~???~?_=p?J . 但是AesReader(也在下面)一致地解密文件的内容为zW?D?4?rc?~???~?_=p?J Any ideas where I am going wrong? 我出错的任何想法?

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 suggestion by erickson: 基于erickson建议的工作代码:

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);
        }
    }
}

Full code isn't shown, but it looks like you are writing hex-encoded text into the file, but reading it without decoding back to bytes. 未显示完整代码,但看起来您正在将十六进制编码的文本写入文件,但是在不解码回字节的情况下读取它。 Skip the hex encoding (I assume that was to help you debug). 跳过十六进制编码(我假设这是为了帮助您调试)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM