6

スタック オーバーフローで既に尋ねようとしている質問と同様の質問がたくさんあることを認識していますが、どれも私のニーズを本当に満たす明確な回答を持っていないので、ここで説明します。

私のプログラムは、ネットワーク経由で ASN.1 でエンコードされた RSA 公開鍵を受け取ります。単純な NSData インスタンスにデータを格納しています。その公開鍵を使用して 16 バイトのデータをエンコードし、それらをネットワーク経由で返したいと考えています。私の調査によると、これを行う最善の方法は SecKeyRef を使用することです。Apple が提供する途方もなくあいまいなドキュメントによると、これはいくつかのコードを使用して行うことができます。ただし、彼らのコードには問題があります。公開鍵を使用するたびに、それをキーチェーンに追加して一意の識別子を付与する必要があります。これに関する問題は、このキーが1 回しか使用されないことです。キーチェーンになく、ASN.1 でエンコードされたキーから作成されたキーの SecKeyRef を取得する方法を探しています。

また、base64 エンコードで一般的な PEM に変換し、'-----BEGIN PUBLIC KEY-----' と '-----END PUBLIC KEY-----' でラップする可能性も検討しました。 ' そしてそれを SecKeyRef にロードしますが、これを行う方法も見たことがありません。

また、キーのタイプ、キーの形式などにあまり選択肢がありません。サードパーティのJavaサーバーからのものです。わーい。

私は現在、(おそらく)キーをキーチェーンに追加しないキーをロードするこの代替方法を持っていますが、キーは明らかに(試行錯誤による:D)DER形式ではないため、このようにロードできません。

SecCertificateRef certificateRef = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)data); //data contains the public key - received over the network
SecPolicyRef policyRef = SecPolicyCreateBasicX509();
SecTrustRef trustRef;

OSStatus status = SecTrustCreateWithCertificates(certificateRef, policyRef, &trustRef);
NSAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates failed.");

SecTrustResultType trustResult;
status = SecTrustEvaluate(trustRef, &trustResult);
NSAssert(status == errSecSuccess, @"SecTrustEvaluate failed.");

SecKeyRef publicKey = SecTrustCopyPublicKey(trustRef); //The Result :)
NSAssert(publicKey != NULL, @"SecTrustCopyPublicKey failed.");

if (certificateRef) CFRelease(certificateRef);
if (policyRef) CFRelease(policyRef);
if (trustRef) CFRelease(trustRef);

PS: なぜアップルはこれを難しくしているのですか? OpenSSL を静的にリンクするのは簡単ですが、そうするとあらゆる種類の輸出規制やその他の問題が適用されます。

4

1 に答える 1

0

問題は明らかに「証明書」のソースにありましたが、これは実際にはいくつかの DER タグにラップされたキー以上のものではありませんでした。

このhttp://blog.wingsofhermes.org/?p=75ブログ投稿のブラック マジックのおかげで、目標のほとんどを達成することができました。

成功:

  • ファイルではなく、データから読み込まれたキー
  • シークレット (AES) 鍵の暗号化が Java サーバーによって正常に読み取られました。

成功率が低い:

  • 一意の識別子を使用する必要がありましたが、私はそれを再利用するので、クレイジーな命名スキームは必要ありません。
  • キーは一時的にキーチェーンに追加されますが、1 回使用すると削除されるので、それもうまくいきます。

ループと多数のマジック ナンバーを組み合わせた if ステートメントの配列が正確に何をするのかはまだはっきりしていませんが、少なくとも機能し、キーは常に同じソースから取得されるため、 Javaセキュリティプロバイダー...ああ、それは実際にはちょっとありそうです...ああ、まあ...少なくともJava 7標準では少し具体的です。

*指を交差させます* *何も壊れないことを願っています*

于 2013-07-22T01:53:04.370 に答える