13

Java アプリケーションで Yubikey NEO OpenPGP スマート カード アプレットに基づく PGP 暗号化を実装しようとしています。それは暗い芸術のようで、このようなものをグーグルで検索するのは簡単ではありませんが、これまでのところ私が得た場所は次のとおりです。

  1. カードが初期化され、キーが gpg ツールを使用して生成されます。それは一般的に機能します。公開鍵が.ascフォーマットされていて、なんとかロードできましたorg.bouncycastle.openpgp

  2. javax.smartcardioAPIを使用して USB ドングルのスマート カードに接続します。

  3. OpenPGP アプレットを選択します

    val pgpAID = bytes(0xD2, 0x76, 0x00, 0x01, 0x24, 0x01)
    val answer = cardChannel.transmit(CommandAPDU(0x00, 0xA4, 0x04, 0x00, pgpAID))
    
  4. 正しい PIN をカードに正しく提示する

    val pin = "123456"
    return bytes(0x00, 0x20, 0x00, 0x82, pin.length) + pin.toByteArray(Charsets.UTF_8)
    
  5. 準成功 (以下を参照)decipherコマンドを送信する

    bytes(0x00, 0x2a, 0x80, 0x86, data.size) + data + bytes(0x00)
    

    の場合data = "xxxx".toByteArray()、結果はSW=9000(= 成功) ですが、データは返されません。52ページのOpenPGPアプレットのドキュメントに次のように記載されているため、これは単純なテストです。

    コマンド入力 (パディング インジケータ バイトを除く) は、暗号化の前に PKCS#1 に従ってフォーマットされます。

データを暗号化して PKCS#1 形式にする方法がわかりません。

Yubico OpenPGP カードの実装テストも読んでみましたが、別の「失敗した」例 (196 行目) しか提供されていません。私はそれを実行しようとしましたが、結果は異なります: テストは期待してSW=0050います (例外を示していますか?) と、私が得たものは(このドキュメントSW=6f00によると、正確な診断はありません) です。

コード全体を含むGitHub リポジトリを作成しました。Kotlin で書かれていますが、読みやすいはずです。

4

1 に答える 1

6

あなたの質問はやや混乱していますが、スマートカードの RSA 秘密鍵に対応する RSA 公開鍵を使用して PGP 暗号化メッセージを作成し、スマートカードの RSA 秘密鍵を使用してそれらを復号化することを望んでいると確信しています。PGP (実質的に他のすべてのものと同様) はハイブリッド暗号化を使用するため、関連する部分の PGP 暗号化メッセージは次のもので構成されます。

  • ランダムに生成された作業鍵を使用して、TDES や AES などの適切な対称アルゴリズムで暗号化された実際のメッセージを K と呼びます
  • 作業鍵 K と、受信者の公開鍵を使用して RSA によって暗号化されたいくつかのメタデータと、元の PKCS#1 標準によって定義されたパディングが含まれます。現在、公式には RSAES-PKCS1-v1_5 と呼ばれていますが、いまだに不正確に P​​KCS1 と広く呼ばれています。

bcpgGnuPG や BouncyCastle のライブラリなど、標準を実装するソフトウェアは暗号化手順を実行できるため、暗号化手順を実行する必要はありません。自分でやりたい場合は、おそらく偽の K を使用し、実際のメッセージを使用しないテスト データの場合、パディングRSA 剰余累乗を行う必要があります。Java では、少なくとも Oracle または openjdk Java と標準の暗号化プロバイダーを使用すると、javax.crypto.Cipher取得した a を.getInstance("RSA/ECB/PKCS1Padding")通常の方法で使用できます。

「PKCS1」暗号化パディング (RSA 用) は、そのドキュメントの 52 ページの下部と 53 ページの上部に記載されているとおりです。内容は同じですが、現在の OpenPGP 仕様(およびそれ以前) とは形式が異なります。現在に近い PKCS#1 仕様(およびそれ以前) と事実上同一であり、すべて次のように述べられています。

  • 1 バイト 00
  • 1 バイト 02
  • 結果を正しい長さにし、安全にするのに十分なゼロ以外のランダムなバイト
  • 1 バイト 00
  • 「平文」。PGP 暗号化の場合、実際には、PGP 仕様で指定されているようにフォーマットされた作業対称鍵 K です。

段落の始まりに注意してください

AESアルゴリズムの場合

前のページで説明されているように、PGP AFAICS ではなく、別のオプションのようです。

オプション (拡張機能で発表) により、カードは特別な DO (D5) に格納された AES キーを使用したプレーン テキストの復号化をサポートします。これは、証明書または公開鍵が存在せず、外界にカードと共通の秘密がある場合に役立ちます。

だから無視してください。

于 2015-11-22T20:28:18.550 に答える