我正在尝试使用以下代码段解密文件,该文件使用32字节密钥加密.因此,当我尝试加密文件数据时,一切正常.但是当我尝试解密时,程序甚至不会if (cryptStatus == kCCSuccess)
在CryptoExtensions.m中传递条件.我真的很累,想出一个问题.我试图使用Base64解码,但我的文件以UTF8编码保存,所以当我把它的内容放在NSData的日志中时我没有问题:
NSData *fileData = [[[NSData alloc] initWithContentsOfFile:destPath] autorelease];
NSLog(@"File data:%@",[[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding]);
Run Code Online (Sandbox Code Playgroud)
但是当我试图解密它时,我nil
从CryptoExtensions方法获得:
NSData *aesResponse = [fileData AES256DecryptWithKey:@"4QXcCZlgRAIchiaqkMVpF3nkpARmdL3z"];
NSLog(@"AES:%@",[[NSString alloc] initWithData:aesResponse encoding:NSUTF8StringEncoding]);
Run Code Online (Sandbox Code Playgroud)
这是crypto片段的内容:
CryptoExtensions.h
#import <Foundation/Foundation.h>
@interface NSData (CryptoExtensions)
- (NSData*)AES256EncryptWithKey:(NSString*)key;
- (NSData*)AES256DecryptWithKey:(NSString*)key;
@end
Run Code Online (Sandbox Code Playgroud)
CryptoExtensions.m
#import "CryptoExtensions.h"
#import <CommonCrypto/CommonCryptor.h>
@implementation NSData (CryptoExtensions)
- (NSData*)AES256EncryptWithKey:(NSString*)key {
// '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:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess)
{
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer); //free the buffer;
return nil;
}
- (NSData*)AES256DecryptWithKey:(NSString*)key {
// '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:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesDecrypted);
if (cryptStatus == kCCSuccess)
{
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer); //free the buffer;
return nil;
}
@end
Run Code Online (Sandbox Code Playgroud)
此代码存在重大安全问题.它错误地构造了AES密钥,大大减少了密钥空间并且没有IV,从而为第一个块创建了问题.我强烈建议不要使用此代码.
通过开发这个常用代码片段的替代品,我已经完成了大部分工作.请参阅https://github.com/rnapier/RNCryptor.如果它对您不起作用,请告诉我.我试图让它足够容易用于人们将停止使用的所有常见情况AES256EncryptWithKey
.
有关此代码问题的更长时间的讨论,请参阅使用CommonCrypto使用AES正确加密.我喜欢有人将AES加密包装成一个易于使用的类别.我只是希望它没有那么多安全问题.
编辑:回到你的实际问题,你是否用它AES256EncryptWithKey
来加密这些数据?如果没有,则具体格式可能完全不同.几乎每个AES加密实现都使用不同的方法来生成其输入参数,然后生成其输出(大多数都不能很好地记录这一点).您必须匹配参数和格式.例如,您不能使用AES256EncryptWithKey
解密生成的内容openssl enc
.
归档时间: |
|
查看次数: |
7224 次 |
最近记录: |