web-dev-qa-db-ja.com

NFC Android(Ntag213 vs Ultralight C)

私は基本的に、NFC Androidデバイスのタグからテキストを読み書きして、カードに残高を保存するための(大学)プロジェクトを持っています)たとえば、食堂で使用されます)。

現在、私はNtag21を使用して以下のコードを実行しています:

ndef.connect();
NdefRecord mimeRecord = NdefRecord.createMime("text/plain", messageEncrypted.getBytes(Charset.forName("US-ASCII")));
ndef.writeNdefMessage(new NdefMessage(mimeRecord));
ndef.close();

お気づきのとおり、私はメッセージをタグに書き込む前にアプリケーションレベルの暗号化を使用してメッセージ(messageEncrypted)を暗号化しています( 'com.scottyab:aescrypt:0.0.1'ライブラリを使用したAES-256暗号化) -非常に大きなパスワードキーを使用し、その一部として各タグUUIDと組み合わせます)。

これまでのところ良好-タグのデータを理解できるのは私だけです。

私の研究では、セキュリティに関してはltralight C> Ntag21であることがわかりました。

**私は両方のタグのスペースが限られていることを知っていますが、それで十分です。


質問1)アプリケーションレベルの暗号化を使用する場合、Ntag213よりもUltralight Cのほうが安全なのはなぜですか?

質問2)アプリケーションレイヤーでAES暗号化を使用してセキュリティを保証できると確信していますが、(私以外の)人々が保存されたデータをいじりたくありません(タグのフォーマットまたはそこへの情報の書き込み-私がそれを決定することができたとしても)。これを防ぐ唯一の方法は(間違っている場合は修正してください)、タグにパスワードを設定することです。ただし、Ntag213とUltralight Cはどちらも32ビットのパスワードしか持っていません。十分ですか? (私以外の)誰かがデータを書き込むのを防ぐ別の方法はありますか?

質問3)このようなタグに対して、セキュリティを強化するために使用できる他のセキュリティ対策はどれですか(タグおよびアプリケーションレイヤー)? Ultralight Cには3DES認証があることがわかりますが、Android=の例はこれまで見つかりませんでした。

質問4)タグのセキュリティを比較するとき(Mifare Desfire> Ultralight> Ntag213> Mifare Classic)、実際には何が比較されていますか? (ネイティブタグの)暗号化を解読することの容易さ、または許可なくタグの1つのストア(何でも)を容易にすること?

質問5)より安全な他の技術(Mifare Desfire、ICODE SLIX、Infineon Cipurse)がたくさんあるので、私が使用している技術(Ntag213またはUltralight C)が誰かのバランスを保存するのに十分良い。アプリケーションレベルの暗号化と32ビットパスワードを備えたNtag213は、このタイプのアプリケーションに十分適していると思いますか(個人的な意見ですが)。そして、実際に誰かがそのセキュリティを破るのにどれくらいの時間がかかりますか?

2
pedrofialho

このコードでは、攻撃者はシステムに有効なメッセージforgeを実行できません。ただし、作成した(有効な)メッセージをコピーして他のタグに貼り付けたり、以前の状態に復元したりできます。

これは、これが可能であることを意味します。

  1. アカウントの残高(タグに保存されている場合)を購入前の状態に復元します(購入前にタグをコピーし、購入後に復元するだけです)。
  2. 他の誰かのアカウントと共有します(タグを放置したままにしておくと、攻撃者がそれをコピーして別のタグに貼り付け、偽装してさらに購入することができます)。

ケース1を制限するためにデータベース(タグごと)を使用してオンラインで残高を確認している場合でも、スキームでケース2を防ぐことはできません。

32ビットのパスワード保護は、パスワードを知らない限り(「アクセス不可」ゾーンを設定するためにパスワードを使用することはないと思うので)、タグの内容の変更を防ぐだけですが、単純な$ 100ツールを使用する人なら誰でもパスワードを取得できます有効なタグは平文で送信されるため(MITMはこちら)、操作するときは必要です。

上記のような悪用を防ぐには、次のような方法が必要です。

  1. パスワード/秘密鍵を平文で送信しません
  2. リーダーとタグがふりをするものであることを確認するために、ランダムな(アクセスごとに異なる)セッションキーを作成します。
  3. そのセッションキーを使用して、タグのデータにアクセス/変更します

これは、Mifare Ultralight C(またはDESFire)タグでのみ可能です(暗号が壊れているため、Mifare Classicは使用しないでください)。

通常、このようなタグでは、タグの一意の識別子を使用してper-tagper-sytem秘密鍵を作成します。このキーを使用して、タグのブロックで認証し、タグUIDから派生した別のキーで暗号化された残高/メッセージを保存します。また、可能であれば、各認証後にキーをローテーションする必要があります。

認証が有効な場合、タグは複製されておらず、以前の状態から復元されていません。

したがって、プロセスの明確な図を作成するには:

  let M = message to store on tag
  let transaction = the current transaction counter you need to store in a database
  let Secret1 = some secret random value for your system (16 bytes for 3DES key). Depending on your security need, you might need to derive this secret from the reader's unique identifier.
  let Secret2 = some another secret random value for your system (16 bytes for AES key)

  When a tag is enrolled:
    let UID = tag UID
    transaction = 0
    let authKey = Hash(UID, Secret1, transaction)
    let msgKey = AES_CTR(M, Hash(UID, Secret2, transaction))
    change KeyA from default to authKey
    authenticate with authKey on some sector
    write msgKey
    store (UID, transaction) in your database

  When the tag is used:
    let UID = tag UID
    let authKey = Hash(UID, Secret1, transaction)
    authenticate with authKey on same sector
    if (authencation failed) reject tag or kill it, exit
    read msgKey from the sector's data
    extract M = AES_CTR(msgKey, Hash(UID, Secret2, transaction))
    if (M isn't good) reject tag or kill it, exit
    Perform your system's intended action, this gives M'
    increment transaction
    compute msgKey = AES_CTR(M', Hash(UID, Secret2, transaction))
    write msgKey to sector
    compute authKey = Hash(UID, Secret1, transaction)
    change authentication's key with new authKey
    update database's transaction count.

データベースがない場合(リーダー上、またはシステムがオンラインでない場合)、攻撃者はNFCツールを使用してエミュレートするため、タグのコピーと復元を防止できません。ウルトラライトCカードを使用して、登録時にブロックのコンテンツをキャプチャします(内部の内容を理解できない場合でも)。これはハイテク技術であるため、保護できる資産の価値によっては、意味がない場合があります。

Mifareには、ブロックに値を格納できる機能がいくつかあり、正しいキーがある場合は、タグに値を増加または減少させることができます。これを上記の疑似コードで実装するのは簡単ですが、タグがバランスを保存している場合にのみ機能します(理解してください:メッセージではありません)。

これで概要がわかったので、質問に答えましょう。

  1. 超軽量Cは認証を許可するため、NFCプローブを使用したMITMによるパスワードのキャプチャを防止します(使用する場合、明らかに他の利点はありません)
  2. パスワードは無意味です。すべてのリーダーを制御できない場合、つまり、タグをスライドトレイに配置し、スライドさせて、電子ギズモ用のスペースがないマシン内部で読み取れるようにすると、役に立たなくなります。
  3. 認証が必要です。秘密のセッションキーを導出する方法がなければ、MITMからの保護はありません。 Androidの場合はわかりません。
  4. トラックを透明なビニール袋と比較するようなものです。どちらもリンゴを保管できます。しかし、前者はより高価ですが、より多くのものを入れたり、ドアをロックしたりするなど、より多くのことができます。リンゴを見て、追加/削除する人を気にしない場合は、ビニール袋、安いです。
  5. ここでDESFireまたはICodeを使用することには、システムにとって実際の利点はありません。実際には追加のストレージスペースは必要ありません。3DESは、ここのカフェテリアのバランスを保護するのに十分安全です。学生の食堂のアカウントの$ 20のバランスを破ろうとするために、数千ドルとは言わないまでも数百ドルのコンピューティング能力を支払う経済的な意味はありません。

使いやすさの観点から、Android電話をISO14443-4 NFCタグとして使用することができるため、ランダムなUIDを使用するため、上記のスキームはDESFireもISO14443-4に準拠しているため、AndroidのNFCを実行する場合でも、そのような電話や機能を持たない人のためにDESFireタグを販売および使用できます。

繰り返しますが、これを正しく行うには多くの開発が必要であり、比較的単純なUltralight Cシステムや支払い用のWebベースのアプリケーションと比較して、それが理にかなっているかどうかはわかりません。

1
xryl669