我想我回答這個問題有點遲了......希望答案對其他人有用。
無論如何,蘋果提供這些方法來包裝/解包的關鍵:
- 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);
問候。
這是OS X,不是iOS –
我需要iOS(iPhone)中的這個功能。如果你指的是我鏈接的文檔,那麼確定。我發現很難從閱讀中看出它是否僅適用於OS X或iOS。我在網絡上看到iOS擁有AES Wrapping的一些圖片,但我不知道我是否理解它,或者它是否暴露在應用程序中。 – ykaganovich
似乎iOS沒有內置AES封裝爲OS X. –