【发布时间】:2011-04-19 21:27:13
【问题描述】:
是否有可能找出使用 SecKeyGeneratePair(一般的安全框架)创建的公钥的模数和指数?
【问题讨论】:
-
对于任何关心的人:我前段时间通过使用 OpenSSL 解决了我的问题。
-
请分享解决方案...这会有所帮助:)
标签: iphone objective-c cocoa-touch encryption rsa
是否有可能找出使用 SecKeyGeneratePair(一般的安全框架)创建的公钥的模数和指数?
【问题讨论】:
标签: iphone objective-c cocoa-touch encryption rsa
对此我一头雾水,但这是我找到的解决方案(不使用任何外部包)。
首先,转到 Apple 的 CryptoExercise 示例。从那里下载“SecKeyWrapper”类。该类中有趣的函数是 getPublicKeyBits。
示例链接:http://developer.apple.com/library/ios/#samplecode/CryptoExercise/Introduction/Intro.html
您将收到的位是 DER 编码的(wiki it)公钥,其中包含模数和 exp。这是一个可以为您解码的代码,非常简单:
- (NSData *)getPublicKeyExp
{
NSData* pk = [self getPublicKeyBits];
if (pk == NULL) return NULL;
int iterator = 0;
iterator++; // TYPE - bit stream - mod + exp
[self derEncodingGetSizeFrom:pk at:&iterator]; // Total size
iterator++; // TYPE - bit stream mod
int mod_size = [self derEncodingGetSizeFrom:pk at:&iterator];
iterator += mod_size;
iterator++; // TYPE - bit stream exp
int exp_size = [self derEncodingGetSizeFrom:pk at:&iterator];
return [pk subdataWithRange:NSMakeRange(iterator, exp_size)];
}
- (NSData *)getPublicKeyMod
{
NSData* pk = [self getPublicKeyBits];
if (pk == NULL) return NULL;
int iterator = 0;
iterator++; // TYPE - bit stream - mod + exp
[self derEncodingGetSizeFrom:pk at:&iterator]; // Total size
iterator++; // TYPE - bit stream mod
int mod_size = [self derEncodingGetSizeFrom:pk at:&iterator];
return [pk subdataWithRange:NSMakeRange(iterator, mod_size)];
}
- (int)derEncodingGetSizeFrom:(NSData*)buf at:(int*)iterator
{
const uint8_t* data = [buf bytes];
int itr = *iterator;
int num_bytes = 1;
int ret = 0;
if (data[itr] > 0x80) {
num_bytes = data[itr] - 0x80;
itr++;
}
for (int i = 0 ; i < num_bytes; i++) ret = (ret * 0x100) + data[itr + i];
*iterator = itr + num_bytes;
return ret;
}
【讨论】:
我尝试了这种方法,它可以很好地提取指数。正如预期的那样,它的大小为 3 个字节,但提取的模数不是正确的大小。模数的大小是 129 字节而不是 128 字节。
代码如下:
- (NSData *)getPublicKeyBits: (NSString*) publicKeyIdentifier {
OSStatus sanityCheck = noErr;
NSData * publicKeyBits = nil;
CFTypeRef pk;
NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init];
NSData* publicTag = [publicKeyIdentifier dataUsingEncoding:NSUTF8StringEncoding];
// Set the public key query dictionary.
[queryPublicKey setObject:(__bridge_transfer id)kSecClassKey forKey:(__bridge_transfer id)kSecClass];
[queryPublicKey setObject:publicTag forKey:(__bridge_transfer id)kSecAttrApplicationTag];
[queryPublicKey setObject:(__bridge_transfer id)kSecAttrKeyTypeRSA forKey:(__bridge_transfer id)kSecAttrKeyType];
[queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge_transfer id)kSecReturnData];
// Get the key bits.
sanityCheck = SecItemCopyMatching((__bridge_retained CFDictionaryRef)queryPublicKey, &pk);
if (sanityCheck != noErr)
{
publicKeyBits = nil;
}
publicKeyBits = (__bridge_transfer NSData*)pk;
//NSLog(@"public bits %@",publicKeyBits);
return publicKeyBits;
}
- (NSData *)getPublicKeyExp
{
NSData* pk = [self getPublicKeyBits:@"RSA Public Key"];
if (pk == NULL) return NULL;
int iterator = 0;
iterator++; // TYPE - bit stream - mod + exp
[self derEncodingGetSizeFrom:pk at:&iterator]; // Total size
iterator++; // TYPE - bit stream mod
int mod_size = [self derEncodingGetSizeFrom:pk at:&iterator];
iterator += mod_size;
iterator++; // TYPE - bit stream exp
int exp_size = [self derEncodingGetSizeFrom:pk at:&iterator];
return [pk subdataWithRange:NSMakeRange(iterator, exp_size)];
return pk;
}
- (NSData *)getPublicKeyMod
{
NSData* pk = [self getPublicKeyBits:@"RSA Public Key"];
if (pk == NULL) return NULL;
int iterator = 0;
iterator++; // TYPE - bit stream - mod + exp
[self derEncodingGetSizeFrom:pk at:&iterator]; // Total size
iterator++; // TYPE - bit stream mod
int mod_size = [self derEncodingGetSizeFrom:pk at:&iterator];
return [pk subdataWithRange:NSMakeRange(iterator, mod_size)];
return pk;
NSLog(@"public size: %d",pk.length);
}
- (int)derEncodingGetSizeFrom:(NSData*)buf at:(int*)iterator
{
const uint8_t* data = [buf bytes];
int itr = *iterator;
int num_bytes = 1;
int ret = 0;
if (data[itr] > 0x80) {
num_bytes = data[itr] - 0x80;
itr++;
}
for (int i = 0 ; i < num_bytes; i++)
ret = (ret * 0x100) + data[itr + i];
*iterator = itr + num_bytes;
return ret;
}
【讨论】:
类似下面的内容更可靠:
+ (NSInteger)keyModulusSize:(NSData *)keyData
{
NSString *randomTag = [NSString ptk_randomStringOfLength:32];
SecKeyRef key = [self addPublicKeyRef:keyData withTag:randomTag];
NSInteger size = 0;
if (key) {
size = SecKeyGetBlockSize(key);
[self removePublicKeyRef:randomTag];
}
return size;
}
【讨论】:
我在开始时删除了那个额外的字节,现在它可以正常工作了。在我的例子中,它总是提取 129 字节的模数。
- (NSData *)getPublicKeyModFromKeyData:(NSData*)pk
{
if (pk == NULL) return NULL;
int iterator = 0;
iterator++; // TYPE - bit stream - mod + exp
[self derEncodingGetSizeFrom:pk at:&iterator]; // Total size
iterator++; // TYPE - bit stream mod
int mod_size = [self derEncodingGetSizeFrom:pk at:&iterator];
// return [pk subdataWithRange:NSMakeRange(iterator, mod_size)];
NSData* subData=[pk subdataWithRange:NSMakeRange(iterator, mod_size)];
return [subData subdataWithRange:NSMakeRange(1, subData.length-1)];
}
【讨论】: