2013-10-15 53 views
2

我们有一个客户端 - 服务器体系结构,服务器使用AES密钥包裹算法(rfc 3394)将包含其他AES密钥的AES密钥返回给客户端。我们需要在iOS上实现一个解开这些密钥的客户端。在iOS上展开AES密钥

我对iOS开发一无所知(我负责服务器和Web服务API,所以我指定了AES Key Wrap,假设这不成问题),并且客户端的人告诉我他们很难实现这一点。

那么,如何才能解开iOS上的AES密钥呢?有没有可以做到这一点的图书馆?我发现this documentation这似乎正是我所需要的,但他们声称它不可用。

+0

这是OS X,不是iOS –

+0

我需要iOS(iPhone)中的这个功能。如果你指的是我链接的文档,那么确定。我发现很难从阅读中看出它是否仅适用于OS X或iOS。我在网络上看到iOS拥有AES Wrapping的一些图片,但我不知道我是否理解它,或者它是否暴露在应用程序中。 – ykaganovich

+0

似乎iOS没有内置AES封装为OS X. –

回答

3

我想我回答这个问题有点迟了......希望答案对其他人有用。

无论如何,苹果提供这些方法来包装/解包的关键:

  • CCSymmetricKeyWrap
  • CCSymmetricKeyUnwrap

它们位于CommonCrypto/CommonSymmetricKeywrap.h和MacOS的还有iOS版可供选择。

使用这2种方法的一个例子是如下(请注意,此代码不能马上使用自己的代码,因为XCTAssert's的):

#import <CommonCrypto/CommonCrypto.h> 

// The size of the Key Encryptions Key has to be: 
// kCCKeySizeAES128 (16), kCCKeySizeAES192 (24) or kCCKeySizeAES256 (32) bytes 
u_int8_t kekBytes[kCCKeySizeAES128] = { 
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 
    0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 
}; 

// The size of the data to cipher has to be a multiple of 64 bits 
u_int8_t plainBytes[2 * sizeof(u_int64_t)] = { 
    0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 
    0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x11 
}; 

// WRAP KEY 

// The size of the ciphered data is equal to the size of the plain data 
// + another 64 bits 
size_t cipheredBytesSize = (sizeof(plainBytes) + sizeof(u_int64_t)); 
u_int8_t cipheredBytes[cipheredBytesSize]; 

CCCryptorStatus status = CCSymmetricKeyWrap(kCCWRAPAES, 
              CCrfc3394_iv, 
              CCrfc3394_ivLen, 
              kekBytes, 
              sizeof(kekBytes), 
              plainBytes, 
              sizeof(plainBytes), 
              cipheredBytes, 
              &cipheredBytesSize); 
XCTAssertEqual(status, kCCSuccess); 
XCTAssertEqual(cipheredBytesSize, sizeof(plainBytes) + sizeof(u_int64_t)); 

// UNWRAP KEY 

size_t sizeDecipheredPlainData = sizeof(plainBytes); 
u_int8_t decipheredPlainBytes[sizeDecipheredPlainData]; 

status = CCSymmetricKeyUnwrap(kCCWRAPAES, 
           CCrfc3394_iv, 
           CCrfc3394_ivLen, 
           kekBytes, 
           sizeof(kekBytes), 
           cipheredBytes, 
           cipheredBytesSize, 
           decipheredPlainBytes, 
           &sizeDecipheredPlainData); 
XCTAssertEqual(status, kCCSuccess); 
XCTAssertEqual(sizeDecipheredPlainData, sizeof(plainBytes)); 

XCTAssertEqual(memcmp(plainBytes, decipheredPlainBytes, sizeof(plainBytes)), 0); 

现在,较早前我编码一个符合RFC 3394以及RFC 5649的库。后者称为带密码的AES密钥包,描述了如何打包/解包大小不是64位倍数的密钥,实际上它可以是任何大小。这个图书馆位于here in GitHub,也可在CocoaPods。但是,说实话,除非你必须包装任何尺寸的密钥,否则使用它没有多大意义。

尽管如此,下面有关于如何使用它的另外一个例子:

#import <CommonCrypto/CommonCrypto.h> 

// The size of the Key Encryptions Key has to be: 
// kCCKeySizeAES128 (16), kCCKeySizeAES192 (24) or kCCKeySizeAES256 (32) bytes 
u_char kekBytes[kCCKeySizeAES128] = { 
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 
    0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 
}; 
NSData *keyEncryptionKey = [NSData dataWithBytes:kekBytes length:sizeof(kekBytes)]; 

// AES Key Wrap 

// The size of the data to cipher has to be a multiple of 64 bits 
u_char plainBytes[2 * sizeof(uint64_t)] = { 
    0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 
    0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x11 
}; 
NSData *expectedPlainData = [NSData dataWithBytes:plainBytes length:sizeof(plainBytes)]; 

NSData *cipheredData = [AKWAesKeyWrap cipheredDataByWrappingPlainData:expectedPlainData 
               withKeyEncryptionKey:keyEncryptionKey 
                   error:nil]; 
NSData *plainData = [AKWAesKeyWrap plainDataByUnwrappingCipheredData:cipheredData 
               withKeyEncryptionKey:keyEncryptionKey 
                   error:nil]; 

XCTAssertEqualObjects(expectedPlainData, plainData); 

// AES Key Wrap with Padding 

// The plain data can be as small as 1 byte 
u_char plainBytesWithPadding[1] = {0x10}; 
expectedPlainData = [NSData dataWithBytes:plainBytesWithPadding length:sizeof(plainBytesWithPadding)]; 

cipheredData = [AKWAesKeyWrap cipheredDataByWrappingWithPaddingPlainData:expectedPlainData 
                usingKeyEncryptionKey:keyEncryptionKey 
                    error:nil]; 
plainData = [AKWAesKeyWrap plainDataByUnwrappingWithPaddingCipheredData:cipheredData 
                usingKeyEncryptionKey:keyEncryptionKey 
                    error:nil]; 

XCTAssertEqualObjects(expectedPlainData, plainData); 

问候。