我在我的应用中使用以下代码进行加密。我刚刚更改了我的应用程序以获得Apple所需的64位支持。由于启用64位,加密不再有效。我不知道加密或解密是否有问题,但是当加密某些数据然后解密时,我最终会变成垃圾。
#import "AES256.h"
#import <CommonCrypto/CommonCryptor.h>
@implementation NSData (AES256)
- (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];
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];
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
更新 我发现我的密钥有问题可能是原因的一部分。密钥创建的一部分使用散列字符串。这种散列函数在32位iPhone上产生不同的摘要值,而不是64位iPhone。我不知道为什么会这样。 keydata长度永远不会超过32位整数。如果我硬编码一个字符串返回此处,加密/解密仍然不起作用,所以仍然存在问题。
+ (NSString *)hashString:(NSString *)string
{
const char *s = [string cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData = [NSData dataWithBytes:s length:strlen(s)];
// This is the destination
uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0};
// This one function does an unkeyed SHA1 hash of your hash data
CC_SHA1(keyData.bytes, (CC_LONG)keyData.length, digest);
// Now convert to NSData structure to make it usable again
NSData *convertedData = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
// description converts to hex but puts <> around it and spaces every 4 bytes
NSString *hash = [convertedData description];
hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];
return hash;
}
更新2:我注意到使用少于16个字节的数据时只会出现问题。 16和更大的作品。
答案 0 :(得分:1)
检查所有 32位和64位加密方法的输入:Key,IV,plaintext。确保它们逐字节相同。追踪任何差异并修复它们。 Crypto旨在为小输入差异提供较大的输出差异。
在某些时候,系统更改可能会在其中一个输入中引入意外更改。
你说整个输出都是垃圾;在那种情况下首先看看钥匙。有故障的IV只会破坏AES中的前16个字节。如果输出被破坏,我很惊讶你没有出现错误的填充错误。
答案 1 :(得分:0)
使用此,
#import "NSString+MD5Addition.h"
#import <CommonCrypto/CommonDigest.h>
@implementation NSString(MD5Addition)
- (NSString *) stringFromMD5{
if(self == nil || [self length] == 0)
return nil;
const char *value = [self UTF8String];
unsigned char outputBuffer[CC_MD5_BLOCK_BYTES];
CC_MD5(value, strlen(value), outputBuffer);
NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_BLOCK_BYTES * 2];
for(NSInteger count = 0; count < CC_MD5_BLOCK_BYTES; count++){
[outputString appendFormat:@"%02x",outputBuffer[count]];
}
return outputString;
}