我想我回答这个问题有点晚了......希望这个答案对其他人有用。
无论如何,Apple 提供了这些方法来包装/解包密钥:
- CCSymmetricKeyWrap
- CCSymmetricKeyUnwrap
它们位于CommonCrypto/CommonSymmetricKeywrap.h
MacOS 和 iOS 中并可在其中使用。
使用这两种方法的示例如下(请注意,由于 ,此代码不能立即在您自己的代码中使用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 Key Wrap with Padding,描述了如何包装/解包大小不是 64 位的倍数的密钥,实际上,它可以是任何大小。该库位于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);
问候。