2013-10-15 50 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); 

問候。