ios - 128 位 AES 加密在 Objective-C 中返回 null

标签 ios objective-c commoncrypto

我正在尝试使用 AES 128 位加密来加密字符串,但转换后的加密数据在转换为字符串时始终返回 null。

NSString *iv = @"fedcba9876543210";
NSString *key = @"0123456789abcdef";
- (NSData *)AES128EncryptWithKey
{
char keyPtr[kCCKeySizeAES128 + 1];
bzero( keyPtr, sizeof( keyPtr ) );

[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, kCCOptionECBMode | kCCOptionPKCS7Padding,
                                      keyPtr, kCCKeySizeAES128,
                                      NULL ,
                                      [self bytes], dataLength,
                                      buffer, bufferSize,
                                      &numBytesEncrypted );
if( cryptStatus == kCCSuccess )
{
    return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
}

这是我的加密函数。

NSData *data = [@"String to encrypt" dataUsingEncoding:NSUTF8StringEncoding];

NSData *encryptedData = [[NSData alloc] init];

encryptedData = [data AES128EncryptWithKey];

NSLog(@"Encrypted Data Length %d", [encryptedData length]);

if (encryptedData != nil)
{
    NSString* myString;
    myString = [[NSString alloc] initWithData:encryptedData encoding:NSUTF8StringEncoding];
    NSString* newStr = [NSString stringWithUTF8String:[encryptedData bytes]];
}

加密后,加密数据长度报告为 16,但在将其转换为 NSString 后返回 null。如果我使用 stringWithUTF16String 来转换它,它会像“軽ﶁែ뼐끨骖퐇”一样返回。这里有什么问题?

最佳答案

try this code

#define kCryptingKey @"1234567890abcdef"    

@implementation Tool

+ (NSString*) crypt:(NSString*)recource
{
    NSData *data = [recource dataUsingEncoding:NSUTF8StringEncoding];
    NSData *encrypt = [self AES128EncryptWithKey:kCryptingKey withData:data];
    return [self stringWithHexBytes:encrypt];
}

+ (NSString*) decryptData:(NSData*)recource
{
    NSData *decrypt = [self AES128DecryptWithKey:kCryptingKey withData:recource];
    return [[NSString alloc] initWithData:decrypt encoding:NSUTF8StringEncoding];
}

+ (NSString*) decrypt:(NSString*)recource
{
    NSData* data=[self decodeFromHexidecimal:recource];
    NSData *decrypt = [self AES128DecryptWithKey:kCryptingKey withData:data];
    return [[NSString alloc] initWithData:decrypt encoding:NSUTF8StringEncoding];
}

+ (NSData *) decodeFromHexidecimal:(NSString*)str
{
    NSString *command = [NSString stringWithString:str];
    command = [command stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSMutableData *commandToSend = [[NSMutableData data] init];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    int i;
    for (i=0; i < [command length]/2; i++) {
        byte_chars[0] = [command characterAtIndex:i*2];
        byte_chars[1] = [command characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [commandToSend appendBytes:&whole_byte length:1];
    }
    return commandToSend;
}

+ (NSData *)AES128EncryptWithKey:(NSString *)key withData:(NSData*)_data
{
    // ‘key’ should be 16 bytes for AES128
    char keyPtr[kCCKeySizeAES128 + 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 = [_data 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, kCCOptionECBMode | kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES128,
                                          NULL /* initialization vector (optional) */,
                                          [_data 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 *)AES128DecryptWithKey:(NSString *)key withData:(NSData*)data
{
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES128+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 = [data 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, kCCOptionECBMode | kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES128,
                                          NULL /* initialization vector (optional) */,
                                          [data 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;
}

+ (NSString*) stringWithHexBytes:(NSData*)_data {
    NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:([_data length] * 2)];
    const unsigned char *dataBuffer = [_data bytes];
    int i;
    for (i = 0; i < [_data length]; ++i) {
        [stringBuffer appendFormat:@"%02lX", (unsigned long)dataBuffer[i]];
    }
    return [[stringBuffer copy] autorelease];
}

@end

关于ios - 128 位 AES 加密在 Objective-C 中返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18416645/

相关文章:

ios - 首次使用后无后端应用程序崩溃

ios - 尝试将 iOS 应用程序与 SIP 连接

ios - Dyld 错误消息 : Library not loaded: @rpath/libswiftAssetsLibrary. dylib

ios - 如何在masterViewController中呈现modalViewController?

objective-c - 用 Common Crypto 替换 OpenSSL 依赖? (Mac App Store 收据验证)

iOS CommonCrypto 引用

ios - CAShapeLayer 的 strokeEnd 上的 KVO

ios - 以编程方式创建的约束有问题

ios - Xamarin iOS 如何缩放 UIView 和 UITableView

ios - 对象C:在CommonCrypto中,如果CCCrypt()不使用选项kCCOptionPKCS7Padding,则结果缓冲区为空