Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find out the modulus and exponent of RSA Public Key on iPhone/Objective C

Is there a possible way to find out the modulus and exponent of the Public Key, created with SecKeyGeneratePair (the Security Framework in general)?

like image 1000
zhar Avatar asked Oct 01 '10 14:10

zhar


1 Answers

Busted my head on this, but here's a solution I've found (without using any external packages).

First, go to Apple's CryptoExercise example. Download the "SecKeyWrapper" class from there. The interesting function in that class is getPublicKeyBits.

Link to the example: http://developer.apple.com/library/ios/#samplecode/CryptoExercise/Introduction/Intro.html

The bits you will receive is a DER encoded (wiki it) public key containing both the modulus and exp. Here's a code that will decode it for you, pretty easy:

- (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;
}
like image 170
Yoav Avatar answered Oct 20 '22 10:10

Yoav