[英]NSMutableData encryption in place using NSInputStream
我正在尝试使用CommonCrypto在适当的地方加密NSMutableData对象(将生成的字节复制到自身,而不复制它)。 以前,我使用CCCrypt()“一次性”方法,主要是因为它看起来很简单。 我注意到我的数据对象在内存中重复了。 为避免这种情况,我尝试使用缓冲区大小为2048字节的NSInputStream对象。 我正在读取我的NSMutableData对象,并连续调用CCCryptorUpdate()来处理加密。 问题是,它似乎仍然是重复的。 这是我当前的代码(请注意,这是NSMutableData上的一个类别 -主要是由于历史原因-因此是“自我”引用):
- (BOOL)encryptWithKey:(NSString *)key
{
// Key creation - not relevant to the dercribed problem
char * keyPtr = calloc(1, kCCKeySizeAES256+1);
[key getCString: keyPtr maxLength: sizeof(keyPtr) encoding: NSUTF8StringEncoding];
// Create cryptographic context for encryption
CCCryptorRef cryptor;
CCCryptorStatus status = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode, keyPtr, kCCKeySizeAES256, NULL, &cryptor);
if (status != kCCSuccess)
{
MCLog(@"Failed to create a cryptographic context (%d CCCryptorStatus status).", status);
}
// Initialize the input stream
NSInputStream *inStream = [[NSInputStream alloc] initWithData:self];
[inStream open];
NSInteger result;
// BUFFER_LEN is a define 2048
uint8_t buffer[BUFFER_LEN];
size_t bytesWritten;
while ([inStream hasBytesAvailable])
{
result = [inStream read:buffer maxLength:BUFFER_LEN];
if (result > 0)
{
// Encryption goes here
status = CCCryptorUpdate(
cryptor, // Previously created cryptographic context
&result, // Input data
BUFFER_LEN, // Length of the input data
[self mutableBytes], // Result is written here
[self length], // Size of result
&bytesWritten // Number of bytes written
);
if (status != kCCSuccess)
{
MCLog(@"Error during data encryption (%d CCCryptorStatus status)", status);
}
}
else
{
// Error
}
}
// Cleanup
[inStream close];
CCCryptorRelease(cryptor);
free(keyPtr);
return ( status == kCCSuccess );
}
我肯定在这里缺少明显的东西,加密,甚至使用输入流对我来说都是新的。
只要只调用CCUpdate()
一次,就可以加密到读取的相同缓冲区中,而无需使用流。 有关示例 ,请参见RNCryptManager.m 。 研究applyOperation:fromStream:toStream:password:error:
我在这里确实使用过流,但是如果您已经有NSData
,则无需这样做。
但是,必须确保CCUpdate()
仅被调用一次。 如果您多次调用它,它将破坏它自己的缓冲区。 这是CommonCryptor( Radar:// 9930555 )中的一个打开的错误。
附带说明:您的密钥生成非常不安全,并且对此类数据使用ECB模式几乎不能视为加密。 它将模式留在密文中,可用于解密数据, 在某些情况下,只需查看即可 。 如果您确实打算保护此数据,则我不建议您使用此方法。 如果您想学习如何很好地使用这些工具,请参阅《 使用CommonCrypto使用AES正确加密》 。 如果需要预包装的解决方案,请参见RNCryptor 。 (但是,RNCryptor当前没有方便的就地加密方法。)
在该行中:
result = [inStream read:buffer maxLength:BUFFER_LEN];
数据被读入buffer
, result
设置为执行结果。 排成一行:
status = CCCryptorUpdate(cryptor, &result, ...
您应该将buffer
用于输入数据,而不是状态
status = CCCryptorUpdate(cryptor, buffer, ...
使用更好的名称将有助于消除简单的错误。 如果将变量而不是result
命名为readStatus
则很可能不会发生该错误。 同样,与其命名数据变量buffer
而不是命名它为streamData
,也应该更加清楚。 命名不正确确实会导致错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.