java - 解密文件内容时返回不同的字节

标签 java android encryption cryptography

因此,我决定扩展我在密码学方面的知识,但我有以下代码来加密文件内容并稍后解密。

我的问题是,当我解密内容并比较我拥有的两个字节数组(原始内容和解密内容)时,我有两个长度甚至内容不同的数组。 你们中有人能发现我的代码中可能有什么问题吗?原始内容是一个 Base 64 解码的字节数组。

public class KeyStoreHelper {

    public static byte[] decryptAES(FileInputStream fis, byte[] key) throws IOException {

        CipherInputStream cin = null;
        try {

            byte[] keyBytes = getKeyBytes(key);
            Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
            aesCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

            byte[] buffer = new byte[1024];

            ByteArrayInputStream cipherIn = new ByteArrayInputStream(buffer);
            ByteArrayOutputStream cipherOut = new ByteArrayOutputStream();
            cin = new CipherInputStream(cipherIn, aesCipher);

            int length;
            while ((length = fis.read(buffer)) != -1) {
                cin.read(buffer, 0, length);
                cipherOut.write(buffer);
            }

            return cipherOut.toByteArray();
        } catch (InvalidKeyException | NoSuchAlgorithmException
                | NoSuchPaddingException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cin != null) {
                cin.close();
            }
            if (fis != null) {
                fis.close();
            }
        }
        return new byte[1];
    }

    public static void encryptAES(FileOutputStream fos, byte[] plainText, byte[] key) throws IOException {

        CipherOutputStream cos = null;
        try {
            byte[] keyBytes = getKeyBytes(key);
            Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
            aesCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

            cos = new CipherOutputStream(fos, aesCipher);
            cos.write(plainText);
            cos.flush();

        } catch (InvalidKeyException | NoSuchAlgorithmException
                | NoSuchPaddingException e) {
            throw new RuntimeException(e);
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cos != null) {
                cos.close();
            }
            if (fos != null) {
                fos.flush();
                fos.close();
            }
        }
    }

    private static byte[] getKeyBytes(final byte[] key) throws Exception {
        byte[] keyBytes = new byte[16];
        System.arraycopy(key, 0, keyBytes, 0, Math.min(key.length, keyBytes.length));
        return keyBytes;
    }
}

内容是从服务器下载的文件:

原始字节[] = {48,-126,11,123,...}, .length = 2943

解密后的字节[] = {48,-126,11,123,...}, .length = 3072 (!)

为什么我的长度会有这样的差异?

最佳答案

看起来你正在处理文件,但实际上你犯了一些错误:

  • 如果您已有 FileInputStream,则不需要 ByteArrayInputStream
  • 写入CipherOutputStream时,您忽略了从输入流读取的字节数;
  • 您忘记关闭CipherOutputStream

基本上,您确实需要正确处理 Java I/O 流。

关于java - 解密文件内容时返回不同的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45420936/

相关文章:

JavaRX 分页 - 在每次交互中而不是在最后观察 - 通用分页器

java - 如何在 Spring MVC 中处理 HTTP header ?

java - 数字的乘积

Android SQLite 删除行问题

java - Guice 场景中多个注入(inject)器引用出现是不可避免的

android - 在最新检查期间,无法捕获任务 ':app:transformClassesWithDexBuilderForDebug'属性 '$1'的输入文件的快照。

java - 为什么我可以在 Android AIDE 中为最终变量重新分配一个新值?

node.js - Node js - 加密和解密文件

java - java.security.KeyStore使用什么算法加密KeyStore.setKeyEntry()和KeyStore.store()中的privateKey?

encryption - key 散列和非 key 散列之间的区别?