我正在编写一个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;
}
问题是,当我尝试加密4096字节时,它也给我添加了16字节的padd,这对我来说是失败的。我不知道为什么要添加padding,因为4096是128的倍数(大小为aes块)。
正如Zaph所说,正在添加PKCS#7填充物。填充是确定性的,因此也填充了16字节的精确倍数,以确保删除。否则,一般化算法如何知道(1)明文在16字节边界上结束,而(2)明文不在16字节的边界上结束并填充?
您可以使用EVP_CIPHER_CTX_ctrl
和EVP_CIPHER_CTX_set_padding
禁用密码对象上的填充行为。EVP_CIPHER_CTX_set_padding
是EVP_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);
请参见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 位块)和(即使没有更多要加密的内容)? 还是只有?还是只有?