首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AES加密算法对于少数文档格式不解密

AES加密算法对于少数文档格式不解密
EN

Stack Overflow用户
提问于 2014-02-27 15:45:20
回答 3查看 743关注 0票数 2

我正在尝试使用AES加密算法解密文档。

我正在从enc文件中获取密钥并在算法中使用它。

当我尝试解密文档时,我无法解密一些格式的文档,如docx, xlsx, pptx and txt文件。请在下面找到我的代码。

代码语言:javascript
复制
- (NSData *)AES256Decrypt
{

NSString* path = [[NSBundle mainBundle] pathForResource:<filename> ofType:@"enc"];

// fetch key data from the key file
NSData *keyData = [NSData dataWithContentsOfFile:path];

NSUInteger dataLength = [self length];

size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);

size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode,
                                      [keyData bytes], kCCKeySizeAES256,
                                      NULL
                                      [self bytes], dataLength, /* input */
                                      buffer, bufferSize, /* output */
                                      &numBytesDecrypted);

if (cryptStatus == kCCSuccess)
{
    return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}

free(buffer);
return nil;
}

我添加了上面的方法作为NSData的类别。

我尝试在客户端进行加密和解密。即使是该文档也无法正确解密。当我尝试打开解密的文件时,在使用QLPreviewController查看文档时出现office open xml word processing document错误。

我不能找到为什么只有几个文档会发生这种情况。有人能帮我解决这个问题吗?谢谢

EN

回答 3

Stack Overflow用户

发布于 2014-02-28 01:38:42

如果您能够解密一些但不是所有指向可能的填充问题的文件。我注意到您没有提供kCCOptionPKCS7Padding。如果数据不是偶数块大小的倍数,则需要某种形式的填充。(当然,可以使用像CTR模式这样的流密码,但这通常是一个糟糕的选择。)

使用ECB模式(kCCOptionECBMode)真的很糟糕,你真的应该使用CBC,默认模式,以及iv。

请参阅Bob ‘n Alice On Security

原创

ECB模式(Eve爱ECB)

CBC模式

看到区别了吗?还想用ECB吗?

票数 1
EN

Stack Overflow用户

发布于 2014-03-08 11:08:24

我遇到的第一个问题是,您已经指定了AES128算法,但是还为AES256算法设置了密钥长度。据我所知,您需要使用与算法匹配的密钥长度。

我将按如下方式更改CCrypt调用,并查看是否可以解决此问题。

代码语言:javascript
复制
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode,
                                      [keyData bytes], kCCKeySizeAES128,
                                      NULL
                                      [self bytes], dataLength, /* input */
                                      buffer, bufferSize, /* output */
                                      &numBytesDecrypted);

当然,如果您打算使用AES256,请执行以下操作:

代码语言:javascript
复制
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES256, kCCOptionECBMode,
                                      [keyData bytes], kCCKeySizeAES256,
                                      NULL
                                      [self bytes], dataLength, /* input */
                                      buffer, bufferSize, /* output */
                                      &numBytesDecrypted);

对于解密,您实际上不需要填充输出缓冲区大小,尽管这样做肯定不会有什么坏处。

其次,与其使用malloc作为输出缓冲区,不如使用NSMutableData。下面是我用来成功完成类似操作的一些代码:

代码语言:javascript
复制
NSMutableData * buffer = [NSMutableData dataWithLength:bufferSize];
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES256, kCCOptionECBMode,
                                      [keyData bytes], kCCKeySizeAES256,
                                      NULL
                                      [self bytes],
                                      dataLength,
                                      buffer.mutableBytes,
                                      buffer.length,
                                      &numBytesDecrypted);

if (cryptStatus == kCCSuccess)
{
    [buffer setLength:numBytesDecrypted];
    return buffer;
}
return nil;

最后,在Rob Napier的著作中可以找到关于Crypto内容的一个很好的资源。首先,请参阅http://robnapier.net/aes-commoncrypto/

票数 1
EN

Stack Overflow用户

发布于 2014-02-27 15:57:25

我在这里看到一个问题:

代码语言:javascript
复制
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode,
                                  [keyData bytes], kCCKeySizeAES256,
                                  NULL
                                  [self bytes], dataLength, /* input */
                                  buffer, bufferSize, /* output */
                                  &numBytesDecrypted);

在这段代码中,[keyData bytes]应该是您的密码。但您正在执行以下操作:

代码语言:javascript
复制
NSData *keyData = [NSData dataWithContentsOfFile:path];

您的文档数据应该在您当前具有[self bytes]的位置的参数中传递。

编辑:在看到你的评论后,我意识到文件中包含了密钥。

我在我的一个项目中使用了AES,并且使用了以下代码:

代码语言:javascript
复制
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char * keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
bzero( keyPtr, sizeof(keyPtr) ); // fill with zeroes (for padding)
// fetch key data
[key getCString: (char *)keyPtr maxLength: sizeof(keyPtr) encoding: NSUTF8StringEncoding];

最后一行'key‘是我的密码。我像这样调用CCCrypt函数:

代码语言:javascript
复制
CCCryptorStatus result = CCCrypt( kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                 keyPtr, kCCKeySizeAES256,
                                 NULL /* initialization vector (optional) */,
                                 [self bytes], dataLength, /* input */
                                 buffer, bufferSize, /* output */
                                 &numBytesDecrypted );
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22062165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档