Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verify digital signature with public key in iOS

How to Verify digital signature with public key in iOS without using any third party code(e.g.) open SSL?

I need to verify Digital signature in iOS App with a public key. Can some one help me how to achieve that without using third party software.

I am trying below code but the problem is I don't have certificate in my App so can not create SecTrustRef.

CODE:

    NSString *certPath              = [[NSBundle mainBundle] pathForResource:@"yyy" 
                                                             ofType:@"xxx"];
    SecCertificateRef myCertificate = nil;
    NSData *certificateData         = [[NSData alloc] initWithContentsOfFile :certPath];
    myCertificate                   = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificateData);

    SecPolicyRef myPolicy           = SecPolicyCreateBasicX509();
    SecTrustRef trustRef;
    SecTrustCreateWithCertificates(myCertificate, myPolicy, &trustRef);
    SecKeyRef keyRef      = SecTrustCopyPublicKey (trustRef);


    BOOL status = SecKeyRawVerify (keyRef,
                              kSecPaddingPKCS1SHA1,
                              (const uint8_t *)[data bytes],
                              (size_t)[data length],
                              (const uint8_t *)[signature bytes],
                              (size_t)[signature length]
                              );

I have the following:

  • Public Key (NSString*)
  • Signature (NSString*)
  • Data (NSString*)

Please help me what all option I have in iOS SDK if I don't want to use ant third party open source.

like image 543
Madhu S. Kapoor Avatar asked Nov 12 '22 08:11

Madhu S. Kapoor


1 Answers

You can package your public key in a X509 certificate to use the iOS built in functions easily, using openSSL:

openssl req -x509 -out public_key.pem -outform pem -new -newkey rsa:2048 -keyout private_key.pem 

the PEM format is base64 encoded, you can switch the -outform to DER to get binary file. you can import the PEM format by adding a const NSString to your program and adding category to NSData with this function:

- (id) initWithBase64EncodedString:(NSString *) string {
    NSMutableData *mutableData = nil;

    if( string ) {
        unsigned long ixtext = 0;
        unsigned long lentext = 0;
        unsigned char ch = 0;
        unsigned char inbuf[4], outbuf[3]; // buffer sizes fixed by AOL LLC
        short i = 0, ixinbuf = 0;
        BOOL flignore = NO;
        BOOL flendtext = NO;
        NSData *base64Data = nil;
        const unsigned char *base64Bytes = nil;

        // Convert the string to ASCII data.
        base64Data = [string dataUsingEncoding:NSASCIIStringEncoding];
        base64Bytes = [base64Data bytes];
        mutableData = [NSMutableData dataWithCapacity:[base64Data length]];
        lentext = [base64Data length];

        while( YES ) {
            if( ixtext >= lentext ) break;
            ch = base64Bytes[ixtext++];
            flignore = NO;

            if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A';
            else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26;
            else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52;
            else if( ch == '+' ) ch = 62;
            else if( ch == '=' ) flendtext = YES;
            else if( ch == '/' ) ch = 63;
            else flignore = YES;

            if( ! flignore ) {
                short ctcharsinbuf = 3;
                BOOL flbreak = NO;

                if( flendtext ) {
                    if( ! ixinbuf ) break;
                    if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
                    else ctcharsinbuf = 2;
                    ixinbuf = 3;
                    flbreak = YES;
                }

                inbuf [ixinbuf++] = ch;

                if( ixinbuf == 4 ) {
                    ixinbuf = 0;
                    outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
                    outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
                    outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );

                    for( i = 0; i < ctcharsinbuf; i++ )
                        [mutableData appendBytes:&outbuf[i] length:1];
                }

                if( flbreak )  break;
            }
        }
    }

    self = [self initWithData:mutableData];
    return self;
}

ofcourse you pull this file into the certificateData if you want to use your existing public key just pull it out and write it in a X509 cert format using openSSL

$ openssl rsa -in id_rsa -out pub.der -outform DER -pubout

good luck

like image 128
mindbomb Avatar answered Nov 15 '22 07:11

mindbomb