質問

私は、ASP.NET WebサービスからRSAの公開キーを取得するiPhoneアプリに取り組んでいます。

<RSAKeyValue>
  <Modulus>qdd0paiiBJ+xYaN4TKDdbEzrJJw9xlbRAltb5OPdegjLoW60yOjL/sni52WVsGC9QxpNitZR33dnUscmI0cTJoxkXypPjbD94UpH+p4el2tuKBypHlE7bERApuUp55y8BiRkbQNFH8smZFWDwtIc/PsJryeGf8fAryel8c5V3PU=</Modulus>
  <Exponent>AQAB</Exponent>
</RSAKeyValue>

次に、この応答をanに変換する必要があります NSData * 適切な形式の(いくつかの激しいグーグルから、おそらく 'asn.1 der'バイナリ形式。両方の部分をbase64表現から元のバイナリ値に変換するコードを設定していますが、人生ではできません。私のワンピースバイナリキーを作成する合理的な方法を見つけました。

キーを待っているコードはです -addPeerPublicKey:(NSString *) keyBits:(NSData *) の方法 SecKeyWrapper Appleのクラス CryptoExercise 例プロジェクト(コード ここ).

私はこれを別の方法で実装することを喜んでいます - 私が必要とするのは、単一の文字列を暗号化することです(復号化は必要ありません)。しかし、私が知る限り、このフォーマットギャップを閉じることができれば、組み込みのセキュリティフレームワークには必要なものがあります。キーを変換してWebSviceからベース64エンコードされたベース64を送信する方法がある場合、それは私のために機能しますが、私はそれをそこにエンコードする方法を見つけることができませんでした。

役に立ちましたか?

解決

だから、私は使用しました SecKeyWrapper ランダムキーを生成するためにクラス、次に使用しました -getPublicKeyBits 公開キーのバイナリ表現を取得する方法(どんな形式でも内部で使用される形式)。それが何らかの形のder asn.1であると仮定して、私はそれをhexとしてコンソールに入れてロードしました このプログラム. 。案の定、内部表現はasn.1ですが、RSAキー表現で通常見つけたものの非常に簡素化されたバージョンです。

![SEQUENCE { INTEGER, INTEGER }][2]

バイナリの担当者からその場で構築するのが難しいことではありません。 derエンコードはただ

30 (for SEQUENCE) LL (total sequence byte length) 
02 (INTEGER) LL (modulus byte length) XX XX... (modulus data bytes) 
02 LL XX XX XX... (exponent length and bytes)

簡単にするために、これが私のコードです。 XML+base64にいくつかのGoogle Libsを使用しています。また、AppleのデモコードSecKeyWrapper。見る 私の他の質問 この作業を行うことに関するメモについて。また、そうであることに注意してください いいえ アーク互換;これは読者のための演習として残されています(私は今年前に今書いたのです)。

#define kTempPublicKey @"tempPayKey"
-(NSData *)encryptedDataWithXMLPublicKey:(NSString *)base64PublicKey data:(NSData *)data {
    if(![data length]){
        @throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:@"Data not set." userInfo:nil];
    }
    GTMStringEncoding *base64 = [GTMStringEncoding rfc4648Base64StringEncoding];
    NSData *keyData = [base64 decode:base64PublicKey];
    NSError *err = nil;
    GDataXMLDocument *keyDoc = [[GDataXMLDocument alloc] initWithData:keyData options:0 error:&err];
    if(err){
        NSLog(@"Public key parse error: %@",err);
        [keyDoc release];
        return nil;
    }

    NSString *mod64 = [[[[keyDoc rootElement] elementsForName:@"Modulus"] lastObject] stringValue];
    NSString *exp64 = [[[[keyDoc rootElement] elementsForName:@"Exponent"] lastObject] stringValue];
    [keyDoc release];
    if(![mod64 length] || ![exp64 length]){
        @throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:@"Malformed public key xml." userInfo:nil];
    }

    NSData *modBits = [base64 decode:mod64];
    NSData *expBits = [base64 decode:exp64];

    /* the following is my (bmosher) hack to hand-encode the mod and exp
     * into full DER encoding format, using the following as a guide:
     * http://luca.ntop.org/Teaching/Appunti/asn1.html
     * this is due to the unfortunate fact that the underlying API will
     * only accept this format (not the separate values)
     */

    // 6 extra bytes for tags and lengths
    NSMutableData *fullKey = [[NSMutableData alloc] initWithLength:6+[modBits length]+[expBits length]];
    unsigned char *fullKeyBytes = [fullKey mutableBytes];
    unsigned int bytep = 0; // current byte pointer
    fullKeyBytes[bytep++] = 0x30;
    if(4+[modBits length]+[expBits length] >= 128){
        fullKeyBytes[bytep++] = 0x81;
        [fullKey increaseLengthBy:1];
    }
    unsigned int seqLenLoc = bytep;
    fullKeyBytes[bytep++] = 4+[modBits length]+[expBits length];
    fullKeyBytes[bytep++] = 0x02;
    if([modBits length] >= 128){
        fullKeyBytes[bytep++] = 0x81;
        [fullKey increaseLengthBy:1];
        fullKeyBytes[seqLenLoc]++;
    }
    fullKeyBytes[bytep++] = [modBits length];
    [modBits getBytes:&fullKeyBytes[bytep]];
    bytep += [modBits length];
    fullKeyBytes[bytep++] = 0x02;
    fullKeyBytes[bytep++] = [expBits length];
    [expBits getBytes:&fullKeyBytes[bytep++]];

    SecKeyRef publicKey = [[SecKeyWrapper sharedWrapper] addPeerPublicKey:kTempPublicKey keyBits:fullKey];
    [fullKey release];

    NSData *encrypted = [[SecKeyWrapper sharedWrapper] wrapSymmetricKey:data keyRef:publicKey];
    // remove temporary key from keystore
    [[SecKeyWrapper sharedWrapper] removePeerPublicKey:kTempPublicKey];

    return encrypted;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top