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

禁用AES密码对象上的PKCS#7填充?[重复]

轩辕庆
2023-03-14

我正在编写一个fuse文件系统,我有一个问题。

我正在使用CBC AES加密磁盘中的数据。问题是填充。当密码的大小是例如15字节时是没有问题的,因为它额外增加了1字节。问题是,当我尝试加密4096字节时,它也给我添加了16字节的padd,这对我来说是失败的。我不知道为什么要添加padding,因为4096是128的倍数(大小为aes块)。我需要修改我的c代码,比如说openssl,它只在必要时添加填充,但并不总是。。。

我知道如果明文不是 128 的倍数,它将添加填充。但如果不是呢?我能做什么?

这是我的密码:

    int encrypt_data(unsigned char *plaintext, int plaintext_len, unsigned char *key,
                unsigned char *iv, unsigned char *ciphertext, int algorithm_pos)
{
        EVP_CIPHER_CTX *ctx;

        int len;

        int ciphertext_len;

        /* Create and initialise the context */
        if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();

        /* Initialise the encryption operation. IMPORTANT - ensure you use a key
         * and IV size appropriate for your cipher
         * In this example we are using 256 bit AES (i.e. a 256 bit key). The
         * IV size for *most* modes is the same as the block size. For AES this
         * is 128 bits */
        if(1 != EVP_EncryptInit_ex(ctx, ciphers[algorithm_pos].algorithm(), NULL, key, iv))
                handleErrors();

        /* Provide the message to be encrypted, and obtain the encrypted output.
         * EVP_EncryptUpdate can be called multiple times if necessary
         */
        if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
                handleErrors();
        ciphertext_len = len;

        /* Finalise the encryption. Further ciphertext bytes may be written at
         * this stage.
         */
        if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
        ciphertext_len += len;

        /* Clean up */
        EVP_CIPHER_CTX_free(ctx);

        return ciphertext_len;
}

共有2个答案

养鸿运
2023-03-14

问题是,当我尝试加密4096字节时,它也给我添加了16字节的padd,这对我来说是失败的。我不知道为什么要添加padding,因为4096是128的倍数(大小为aes块)。

正如Zaph所说,正在添加PKCS#7填充物。填充是确定性的,因此也填充了16字节的精确倍数,以确保删除。否则,一般化算法如何知道(1)明文在16字节边界上结束,而(2)明文不在16字节的边界上结束并填充?

您可以使用EVP_CIPHER_CTX_ctrlEVP_CIPHER_CTX_set_padding禁用密码对象上的填充行为。EVP_CIPHER_CTX_set_paddingEVP_CIPHER_CTX_ctrl的宏版本。如下所示:

int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding);

从手册页:

启用或禁用填充。默认情况下,使用标准块填充来填充加密操作,并且在解密时检查并移除填充。如果填充参数为零,则不html" target="_blank">执行填充,加密或解密的数据总量必须是块大小的倍数,否则将发生错误。

我知道如果明文不是 128 的倍数,它将添加填充。但如果不是呢?我能做什么?

禁用密码上下文对象上的填充。库是这样做的:

$ grep -IR EVP_CIPHER_CTX_set_padding *
CHANGES:  *) New function EVP_CIPHER_CTX_set_padding() this is used to
apps/enc.c:            EVP_CIPHER_CTX_set_padding(ctx, 0);
apps/speed.c:                EVP_CIPHER_CTX_set_padding(&ctx, 0);
crypto/cms/cms_pwri.c:    EVP_CIPHER_CTX_set_padding(&kekctx, 0);
crypto/evp/evp.h:int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
crypto/evp/evp_enc.c:int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
crypto/evp/evp_test.c:        EVP_CIPHER_CTX_set_padding(&ctx, 0);
crypto/evp/evp_test.c:        EVP_CIPHER_CTX_set_padding(&ctx, 0);
杨柏
2023-03-14

请参见PKCS#7填充。填充块大小的精确倍数的原因是无法判断是否没有填充,因此必须始终或从不使用填充。考虑数据是4096字节,最后一个字节是0x01。看起来像一个字节的填充,但事实并非如此,它是数据的一部分。

但你应该使用磁盘扇区加密模式,如XTS,XTS只建议全磁盘加密。这就是IEEE标准1619设计的目的。

请参阅XTS加密模式说明。

还有NIST:用于存储设备保密的XTS-AES模式

 类似资料:
  • 我已经在SO上搜索了很多关于完全加密解密示例的要求。事实上,我有很多链接和示例,但没有一个适用于AES-192-CBC模式和AES-256-CBC。 我有下面的例子,这应该是与所有类型的工作,但它只与AES-128-CBC模式。我是Python的新手。谁能帮我一下我哪里错了? 我在窗户上使用Python 3.4,我无法移动到Python 2.7。 虽然这段代码使用192位和256位加密对数据进行加

  • 我一直在尝试用Python实现AES CBC解密。由于加密文本不是16字节的倍数,因此需要填充。没有填充,这个错误浮出水面 "TypeError:奇数长度字符串" 但我找不到在PyCrypto Python中实现PKCS5的适当参考。是否有任何命令来实现这一点?谢谢 在研究了马库斯的建议后,我这样做了。 我的目标实际上是使用此代码解密十六进制消息(128字节)。但是,输出 " ?:" 非常小,un

  • 我对我当前尝试访问的API的加密有以下要求: < li>PKCS7填充方法 < li>CBC加密模式 < li>AES密钥大小256,块大小128 每次我提交带有加密的API时,API似乎都有问题(不幸的是没有产生错误)。 问题: PKCS7填充方法到底是什么,可以用php实现? AES 256很好,但是块大小到底是什么意思? IV到底是做什么的?

  • 问题内容: 我正在使用Bouncy Castle提供的库来加密,解密,签名和验证符号。我这样做是 1.加密数据 2.签名数据 3.将签名字节写入文件 4.从文件读取签名字节 5.验证签名 6.解密数据 我 从使用Java的密码学开始学了 参考 __ 我的问题是在第5步中,当我验证数据时 org.bouncycastle.cms.CMSException:消息摘要属性值与计算值不匹配 我的代码如下

  • 我正在尝试将aes-128-cbc加密与openssl一起使用,我希望密钥需要32位。但是,我注意到当我输入密钥长度为18时,openssl不会给我错误。 但是,如果我在密钥后添加0,直到它是32位,我仍然会得到相同的结果。 有文档说OpenSSL给键添加了填充吗? 编辑:我需要在代码中重现此行为。我得到了密钥,但不能保证密钥是多少位数。

  • 这应该是一个简单的问题,但我无法从openssl文档中找到任何示例或答案。 我想加密128位,应该适合一个加密块。 所以我调用,然后呢? 我是否调用(加密 128 位块)和(即使没有更多要加密的内容)? 还是只有?还是只有?