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

Java中的矢量不随“AES/CBC/PKCS7PADDING”而改变

董琦
2023-03-14

我使用java中的模式“AES/CBC/PKCS7PADDING”在2个设备之间进行通信。

注意:这里我只放了加密代码,但我们有类似的解密代码。

在通信开始时已经发送了IV矢量。然后,我们希望这两个设备交换加密的消息,而不再发送IV。如果我们的理解是正确的,只要没有消息丢失,两个设备都应该知道在异或中使用的当前“向量”是什么。

然而,Java代码并不像我们期望的那样工作:如果我连续调用encrypt()2次,它将产生相同的加密数据。这不是我们所期望的,因为我们认为第一次加密的结果将是第二次加密的“向量”(该向量与明文之间的异或,如https://en.wikipedia.org/wiki/block_cipher_mode_of_operation#cbc)。

private Cipher mEncryptionCipher;

private void createEncryptionCipher(byte[] iv) {

    mEncryptionCipher = null;

    try {
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        mEncryptionCipher = Cipher.getInstance("AES/CBC/pkcs7padding", "BC");
        mEncryptionCipher.init(Cipher.ENCRYPT_MODE, mAESKey, ivParameterSpec);

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }

}


private byte[] encrypt(byte[] data) {

    if (mEncryptionCipher == null) {
        Log.e(TAG, "Invalid mEncryptionCipher!");
        return null;
    }

    try {
        int sizeOfEncryptedData = computeLengthAfterPKCS7Padding(data.length);
        byte[] encodedData = new byte[sizeOfEncryptedData];

        int cipherBytes = mEncryptionCipher.update(data, 0, data.length, encodedData, 0);

        //allways call doFinal
        cipherBytes += mEncryptionCipher.doFinal(encodedData, cipherBytes);

        return encodedData;

    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (ShortBufferException e) {
        e.printStackTrace();
    } catch (STException e) {
        e.printStackTrace();
    }

    return null;
}

共有1个答案

公西修文
2023-03-14

正如其他人所建议的,只要尽可能使用TLS。

否则,至少从TLS的设计(错误)中吸取教训。在TLS1.0(https://www.rfc-editor.org/rfc/rfc2246)中,CBC密码状态是跨独立记录维护的,我认为这就是您试图跨“数据包”进行的操作。在TLS 1.1中(https://www.rfc-editor.org/rfc/RFC5246)对此进行了更改,以便每个记录都包含一个显式的IV。每个记录的IV“应该随机选择,并且必须是不可预测的”。所以每个记录都是独立加密的。

请特别注意RFC5246中安全分析的这一部分:

还有其他陷阱等着您,所以我回到我的第一个建议:尽可能使用TLS。

编辑:Oops,TLS1.1 RFC实际上是https://www.rfc-editor.org/RFC/rfc4346,它有相同的F.3部分。

 类似资料:
  • 这几天我一直在纠结。我需要使用一个接受加密参数的API。API是用C#编写的。请求的加密如下: 算法:AES 密码模式:CBC 填充模式:PKCS7 块大小:128 密钥大小:256 加密字符串的表示形式:Base64 在搜索和尝试了网上建议的那么多东西之后,我仍然无法生成相同的加密值(特别是默认情况下不支持PKCS7,而PKCS5应该工作相同,但事实并非如此)。以下是我尝试过的一些方法: 1)使

  • 问题内容: 我目前正在使用 256个字节的* 密钥大小来用Java加密文件,但是在搜索时我在stackexchange PKCS#5-PKCS#7填充上发现了它,并提到: * PKCS#5填充是8个字节块大小的PKCS#7填充的子集 所以我想知道 相对于上述配置,性能会更好吗? 正如我们所提到的,我们如何在Java中配置块大小 PKCS#7填充适用于从1到255字节的任何块大小。 我的示例代码是

  • 我在使用java AES/CBC/PKCS7Padding加密时遇到了问题。我已经在使用提供程序之前进行搜索和跟踪。但我还是无法得到正确的加密 假设要求是: 加密类型:对称 算法:AES 块大小=128Bit(16字节) 密码模式:CBC 填充模式:PKCS7 加密密钥长度:256 Bit(32字节) 向量初始化长度(IV):128 Bit(16字节) 示例: 普通数据=ABC123 加密数据(b

  • 问题内容: 我正在尝试编写一个简单的Java程序,该程序将使用加密纯文本。有上课: 有可能的用法: 我的输出是,但是执行此命令时: 我得到的东西与Java程序()有所不同。可悲的是,我不知道为什么结果不一样,因为我使用相同的算法和相同的键和iv。这是否意味着我的Java程序无法正常运行?任何帮助,将不胜感激。 问题答案: 两种方法都可以正常工作,但是您正在加密不同的事物。 此处的字符串语法()在字

  • 问题内容: 我有几个库,C#,PHP和Android,它们都以相同的方式加密/解密字符串,因此它们彼此兼容,即C#将数据写入和加密到数据库中,PHP可以成功解密并返回原始字符串。 现在,我需要对标准Java应用程序执行相同的操作,因此我已经从Android库中获取了代码,并且需要库,但是却遇到了异常。据我所知,代码不是特定于Android的,因此应该不是问题。 下面是我的加密功能 当我打电话时,出

  • 问题内容: PHP加密功能 当我尝试使用下面的函数在Java中解密此结果时,我得到的只是“ Test @ string”,而我则是“ @@BKxnfÈ〜¯Ô’M”。有什么想法我错了吗?谢谢 问题答案: 编辑:从Java 8开始,Java现在包括可接受的Base64类。 这条线 看起来错了。而是使用apache commons编解码器类或Harder base64 类。同样,mcrypt使用的默认填