当前位置: 首页 > 知识库问答 >
问题:

在java中使用aes/cbc/pkcs5padding加密后的文件大小是多少

施念
2023-03-14

我尝试在使用套接字发送文件时使用加密和解密。我使用AES/cbc/pkcs5padding算法,首先将IV写入流,然后将文件写入流。

问题是当文件接收时循环不会结束。

我认为这是由于文件大小和加密文件似乎比原始文件小,而我把原始文件的大小给接收者。如果这个假设是正确的,有没有办法计算加密文件的大小?

            SecretKey keySpec = new SecretKeySpec(key, "AES");
            byte[] iv = AES.randomNonce(16);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);

            outputStream = socket.getOutputStream();
            outputStream.write(iv);
            outputStream.flush();
            inputStream = context.getContentResolver().openInputStream(message.getUri());
            cipherOutputStream = new CipherOutputStream(outputStream, cipher);

            long size = message.getSize();
            long written = 0;
            byte[] buffer = new byte[8192];
            int count;
            int percent = 0;
            while (!isStopped && (count = inputStream.read(buffer)) > 0) {
                cipherOutputStream.write(buffer, 0, count);
                written += count;
                int p = (int) (((float) written / (float) size) * 100);
                if (percent != p) {
                    percent = p;
                    if (onProgressListener != null) {
                        onProgressListener.onProgress(percent);
                    }
                }
            }
            cipherOutputStream.flush();
            if (onProgressListener != null) {
                onProgressListener.onEnd(null);
            }

文件接收器

            inputStream = socket.getInputStream();
            fileOutputStream = new FileOutputStream(file);
            byte[] iv = new byte[16];
            inputStream.read(iv);

            SecretKey keySpec = new SecretKeySpec(key, "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);

            cipherInputStream = new CipherInputStream(inputStream, cipher);

            long size = message.getSize();
            long read = size;
            byte[] buffer = new byte[8192];
            int count;
            int percent = 0;
            while (!isStopped && read > 0 && (count = cipherInputStream.read(buffer, 0, (int) Math.min(buffer.length, read))) != -1) {
                fileOutputStream.write(buffer, 0, count);
                read -= count;
                int p = (int) (((float) read / (float) size) * 100);
                if (percent != p) {
                    percent = p;
                    if (onProgressListener != null) {
                        onProgressListener.onProgress(100 - percent);
                    }
                }
            }
            if (onProgressListener != null) {
                onProgressListener.onEnd(Uri.fromFile(file));
            }

共有1个答案

翁烨霖
2023-03-14

不正确的代码

正如PresidentJamesk.polk所评论的,您需要通过调用.close()函数来关闭发送方端的CipherOutputStream,该函数调用doFinal()来完成加密。

衬垫尺寸

对于这种算法,方法应该是在尾端用k-(l mod k)八位字节填充输入,所有八位字节都具有k-(l mod k)的值,其中l是输入的长度。

八位字节是一个字节,k是以字节为单位的块大小,对于AES来说是16

我们需要计算iv_length+message_size_with_padding

16+l+16-(l mod 16)因此,由于填充,最多扩展了16个字节。

请注意,CBC模式容易受到适用的填充oracle攻击。CBC模式只提供机密性。如果您需要完整性和身份验证(您应该)使用带有HMAC的CBC或者更好地使用AES-GCM这样的身份验证加密模式,它根本不需要填充,但是,您也需要存储标记。如果您担心AES-GCM的瞬时重用问题,那么您可以使用AES-GCM-SIV,这是一个防止瞬时滥用的方案。如果您没有义务使用AES,您可以选择ChaCha20-Poly1305,它可能比AES-GCM[1][2]更容易使用。

 类似资料:
  • 问题内容: 我正在尝试在java中加密数据并在ruby中解密数据。 我的代码是…用Java加密 结果是 我希望在Ruby中解密(加密的字符串) Ruby代码是…(错误) 我希望得到 但它返回错误 我认为问题是cipher.padding和key / iv的类型。但是我不知道如何完成红宝石代码。 请让我知道如何完成此代码。 谢谢。 问题答案: Ruby代码有两个问题。 首先,应该使用AES 128时

  • 我有一些问题,解密文本的CryptoJS已经用Java加密。解密应使用AES/CBC/PKCS5Padding完成。加密的字符串是base64编码的,我在尝试解密字符串之前对其进行解码。 这就是Java代码的样子:

  • 我使用JavaAPI生成128bit密钥。下面是我使用的算法: 我可以通过这些方法轻松地使用secretKey加密和解密消息。由于Java默认使用128bit AES加密,因此它使用SHA1生成原始密钥的哈希,并将哈希的前16字节用作AES中的密钥。然后以十六进制格式转储IV和密文。 但是,它返回一个空字符串。

  • 问题内容: 我正在尝试在NodeJs中解密。它在Java中工作。但是我无法在Node中实现相同的功能。 节点版本:8.4 请找到我的NodeJs代码: 请找到有效的Java解密代码 我得到了不同的解密文本。在NodeJ中,我无法获得与Java中相同的结果。另外,我无法修改Java加密代码。所以我必须弄清楚Node中的解密。 你能帮我这个忙吗? 问题答案: 这是Java和Node.js中的完整示例,

  • 我正在加密我的Android应用程序中的一些数据,然后这些数据被发送到一个PHP页面进行解密和处理。 这有帮助吗?

  • 问题内容: 我想知道AES加密后的数据大小,这样我就可以避免主要出于了解大小而缓存我的后AES数据(在磁盘或内存上)。 我使用128位AES 和进行加密。 使用各种输入大小执行的一些测试表明,如下计算的后期加密大小是正确的: 但是我不确定以上公式是否适用于所有可能的输入大小。 在应用AES加密后,是否有一种方法可以计算数据的大小-事先无需缓存(磁盘或内存中的)加密数据即可知道其加密后的大小? 问题