Having trouble decrypting in C# something encrypted on iPhone using RSA

后端 未结 4 1353
轻奢々
轻奢々 2021-02-03 13:00

I\'ve spent two days on this so far and combed through every source at my disposal, so this is the last resort.

I have an X509 certificate whose public key I have stored

4条回答
  •  名媛妹妹
    2021-02-03 13:19

    this is my first answer on stackoverflow, so please forgive me if I do it wrong!

    I can't give you a complete answer, however I had very similar issues when I tried to integrate with PHP - it seems that the format of Apple's certificate files is a little different from that which other software expects (including openssl).

    Here's how I decrypt an encrypted signature in PHP - I actually extract the modulus and PK from the transmitted public key manually and use that for the RSA stuff, rather than trying to import the key:

    // Public key format in hex (2 hex chars = 1 byte):
    //30480241009b63495644db055437602b983f9a9e63d9af2540653ee91828483c7e302348760994e88097d223b048e42f561046c602405683524f00b4cd3eec7e67259c47e90203010001
    //<--------------------------------------------- MODULUS -------------------------------------------------------------------------->< PK > 
    // We're interested in the modulus and the public key.
    // PK = Public key, probably 65537
    
    // First, generate the sha1 of the hash string:
    $sha1 = sha1($hashString,true);
    
    // Unencode the user's public Key:
    $pkstr = base64_decode($publicKey);
    // Skip the  section:
    $a = 4;
    // Find the very last occurrence of \x02\x03 which seperates the modulus from the PK:
    $d = strrpos($pkstr,"\x02\x03");
    // If something went wrong, give up:
    if ($a == false || $d == false) return false;
    // Extract the modulus and public key:
    $modulus = substr($pkstr,$a,($d-$a));
    $pk = substr($pkstr,$d+2);
    
    // 1) Take the $signature from the user
    // 2) Decode it from base64 to binary
    // 3) Convert the binary $pk and $modulus into (very large!) integers (stored in strings in PHP)
    // 4) Run rsa_verify, from http://www.edsko.net/misc/rsa.php
    $unencoded_signature = rsa_verify(base64_decode($signature), binary_to_number($pk), binary_to_number($modulus), "512");
    
    //Finally, does the $sha1 we calculated match the $unencoded_signature (less any padding bytes on the end)?
    return ($sha1 == substr($unencoded_signature,-20)); // SHA1 is only 20 bytes, whilst signature is longer than this.  
    

    The objective-c that generates this public key is:

    NSData * data = [[SecKeyWrapper sharedWrapper] getPublicKeyBits];
    [req addValue:[data base64Encoding] forHTTPHeaderField: @"X-Public-Key"];
    data = [[SecKeyWrapper sharedWrapper] getSignatureBytes:[signatureData dataUsingEncoding:NSUTF8StringEncoding]];
    [req addValue:[data base64Encoding] forHTTPHeaderField: @"X-Signature"];
    

    Using SecKeyWrapper from Apple's example project CryptoExercise (you can view the file here: https://developer.apple.com/iphone/library/samplecode/CryptoExercise/listing15.html)

    I hope this helps?

提交回复
热议问题