私は基本的に、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は、このタイプのアプリケーションに十分適していると思いますか(個人的な意見ですが)。そして、実際に誰かがそのセキュリティを破るのにどれくらいの時間がかかりますか?
このコードでは、攻撃者はシステムに有効なメッセージforgeを実行できません。ただし、作成した(有効な)メッセージをコピーして他のタグに貼り付けたり、以前の状態に復元したりできます。
これは、これが可能であることを意味します。
ケース1を制限するためにデータベース(タグごと)を使用してオンラインで残高を確認している場合でも、スキームでケース2を防ぐことはできません。
32ビットのパスワード保護は、パスワードを知らない限り(「アクセス不可」ゾーンを設定するためにパスワードを使用することはないと思うので)、タグの内容の変更を防ぐだけですが、単純な$ 100ツールを使用する人なら誰でもパスワードを取得できます有効なタグは平文で送信されるため(MITMはこちら)、操作するときは必要です。
上記のような悪用を防ぐには、次のような方法が必要です。
これは、Mifare Ultralight C(またはDESFire)タグでのみ可能です(暗号が壊れているため、Mifare Classicは使用しないでください)。
通常、このようなタグでは、タグの一意の識別子を使用してper-tag、per-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には、ブロックに値を格納できる機能がいくつかあり、正しいキーがある場合は、タグに値を増加または減少させることができます。これを上記の疑似コードで実装するのは簡単ですが、タグがバランスを保存している場合にのみ機能します(理解してください:メッセージではありません)。
これで概要がわかったので、質問に答えましょう。
使いやすさの観点から、Android電話をISO14443-4 NFCタグとして使用することができるため、ランダムなUIDを使用するため、上記のスキームはDESFireもISO14443-4に準拠しているため、AndroidのNFCを実行する場合でも、そのような電話や機能を持たない人のためにDESFireタグを販売および使用できます。
繰り返しますが、これを正しく行うには多くの開発が必要であり、比較的単純なUltralight Cシステムや支払い用のWebベースのアプリケーションと比較して、それが理にかなっているかどうかはわかりません。