Difference between revisions of "Android Software Card Emulation"
m (→Example) |
|||
(37 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | + | '''Software Card Emulation on Android''' |
|
+ | =Before Android 4.4= |
||
− | Software CE is not possible yet on stock Android but patches have been made for CyanogenMod and they are integrated in the official release since v10.1. |
||
− | == |
+ | ==Readings== |
+ | * [http://www.medien.ifi.lmu.de/iwssi2012/papers/iwssi-spmu2012-roland.pdf Software Card Emulation in NFC-enabled Mobile Phones: Great Advantage or Security Nightmare? (pdf)] by Michael Roland, IWSSI2012 |
||
+ | * [http://nelenkov.blogspot.com/2012/10/emulating-pki-smart-card-with-cm91.html Emulating a PKI smart card with CyanogenMod 9.1] by Nikolay Elenkov |
||
+ | * [http://www.simplytapp.com/about.html SimplyTapp] by Doug Yeager |
||
+ | |||
+ | ==Requirements== |
||
Android phone with a PN544 NFC chipset |
Android phone with a PN544 NFC chipset |
||
− | == |
+ | ==Limitations== |
+ | ===ISO14443-4A=== |
||
− | Easiest is to install cyanogenmod 10.1 (or more recent if available), see [[Android#Installing_Cyanogenmod|instructions]] |
||
+ | * '''Random UID''' (starting with "08") |
||
− | ===Example=== |
||
+ | * '''SAK (SEL_RES): 60 ''' |
||
+ | ** Compliant with ISO/IEC 14443-4 |
||
+ | ** Compliant with ISO/IEC 18092 |
||
+ | * '''ATS: 78 33 88 00''' |
||
+ | ** Max Frame Size accepted by PICC: 256 bytes |
||
+ | ** Bit Rate Capability: |
||
+ | *** PICC to PCD, DS=2, bitrate 212 kbits/s supported |
||
+ | *** PICC to PCD, DS=4, bitrate 424 kbits/s supported |
||
+ | *** PCD to PICC, DR=2, bitrate 212 kbits/s supported |
||
+ | *** PCD to PICC, DR=4, bitrate 424 kbits/s supported |
||
+ | ** Frame Waiting Time: 77.33 ms |
||
+ | ** Start-up Frame Guard Time: 77.33 ms |
||
+ | ** Node Address not supported |
||
+ | ** Card IDentifier not supported |
||
+ | * Corresponding ATR: 3B80800101 |
||
+ | |||
+ | ===ISO14443-4B=== |
||
+ | * '''Random PUPI''' |
||
+ | * '''Application Data: 00 00 00 00 ''' |
||
+ | * '''Protocol Info: 33 81 84 ''' |
||
+ | ** Bit Rate Capability: |
||
+ | *** PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported |
||
+ | *** PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported |
||
+ | *** PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported |
||
+ | *** PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported |
||
+ | ** Maximum frame sizes: 256 bytes |
||
+ | ** Protocol types supported: ISO/IEC 14443-4 |
||
+ | ** Frame Waiting Time: 77.33 ms |
||
+ | |||
+ | ===FeliCa=== |
||
+ | The PN544 chip is also able to emulate FeliCa even if it's not (yet) accessible from Android API but this means if an external FeliCa reader is polling the phone it can get something like FeliCa target: |
||
+ | * '''Random ID''' (NFCID2): 01 fe nn nn nn nn nn nn |
||
+ | * '''Parameter (PAD): c0 c1 c2 c3 c4 c5 c6 c7 ''' |
||
+ | * '''System Code (SC): 0f ab''' |
||
+ | |||
+ | ===Delay=== |
||
+ | On a Nexus S locked at 1000MHz and idle, a delay of about 30ms is still measured. It goes to 60ms if CPU is busy or occasionally even higher under "on demand" CPU scheduler. |
||
+ | |||
+ | ==Installation== |
||
+ | Software CE is not possible yet on stock Android but patches [https://github.com/CyanogenMod/android_packages_apps_Nfc/commit/d41edfd794d4d0fedd91d561114308f0d5f83878 have] [https://github.com/CyanogenMod/android_external_libnfc-nxp/commit/34f13082c2e78d1770e98b4ed61f446beeb03d88 been] made for CyanogenMod and they are integrated in the official release since v10.1. |
||
+ | |||
+ | So, easiest is to install cyanogenmod 10.1 (or more recent if available), see [[Android#Installing_Cyanogenmod|instructions]] |
||
+ | ==Example of PKI smartcard== |
||
This example is taken from [http://nelenkov.blogspot.com/2012/10/emulating-pki-smart-card-with-cm91.html this very interesting post] and [https://github.com/nelenkov/virtual-pki-card its source code], adapted for CyanogenMod 10.1 and compiled under Linux in command line. |
This example is taken from [http://nelenkov.blogspot.com/2012/10/emulating-pki-smart-card-with-cm91.html this very interesting post] and [https://github.com/nelenkov/virtual-pki-card its source code], adapted for CyanogenMod 10.1 and compiled under Linux in command line. |
||
<br>It's a small example emulating a card able to do a PIN verify then a signature, a bit like some eIDs. |
<br>It's a small example emulating a card able to do a PIN verify then a signature, a bit like some eIDs. |
||
− | + | ===Compile application=== |
|
Following instructions [[Android_SDK#Android_application_in_command-line|how to compile Android app in command line]] |
Following instructions [[Android_SDK#Android_application_in_command-line|how to compile Android app in command line]] |
||
<source lang=bash> |
<source lang=bash> |
||
Line 83: | Line 131: | ||
$DEV_HOME/bin/AndroidTest.apk || exit 1 |
$DEV_HOME/bin/AndroidTest.apk || exit 1 |
||
</source> |
</source> |
||
− | + | ===Install application=== |
|
<source lang=bash> |
<source lang=bash> |
||
sudo adb install $DEV_HOME/bin/AndroidTest.apk |
sudo adb install $DEV_HOME/bin/AndroidTest.apk |
||
</source> |
</source> |
||
− | + | ===Create certificate=== |
|
As this example is using a certificate to sign data, we need to create it. |
As this example is using a certificate to sign data, we need to create it. |
||
<source lang=bash> |
<source lang=bash> |
||
Line 124: | Line 172: | ||
** choose cert: select this one, ok |
** choose cert: select this one, ok |
||
* Set PIN=1234 |
* Set PIN=1234 |
||
+ | If reading cert fails, check in CyanogenMod developer options that "Protect USB storage" is not activated. |
||
− | ====Reader application==== |
||
+ | <br>Storing certs require that you defined a screen lock PIN too, do it if needed. |
||
+ | |||
+ | ===Reader application=== |
||
Compile: |
Compile: |
||
<source lang=bash> |
<source lang=bash> |
||
Line 141: | Line 192: | ||
<-- 9000 |
<-- 9000 |
||
--> 80020000087369676E206D6521 |
--> 80020000087369676E206D6521 |
||
+ | <-- 7C19AAE869DD6C2A9C4AAB98E65FEFDF88C0764EDDAD1BE660BBA220237BA7F4D46B08080E925737D7D ... |
||
− | <-- 7C19AAE869DD6C2A9C4AAB98E65FEFDF88C0764EDDAD1BE660BBA220237BA7F4D46B08080E925737D7DC56A1437C72236C60C17678642450F0EEC178B95A1465BA5B002802D467A03B71506D7C9F69380FBB0ADE8AA346D5FDD4E37D4E22EB193986298AFC4C9BF6B5DDAF060DA0E30CF2219DE173AF04E16678A21B94897769 9000 (128) |
||
+ | Got signature from card: 7C19AAE869DD6C2A9C4AAB98E65FEFDF88C0764EDDAD1BE660BBA220237BA7F4D46B08080E925737D7D ... |
||
− | Got signature from card: 7C19AAE869DD6C2A9C4AAB98E65FEFDF88C0764EDDAD1BE660BBA220237BA7F4D46B08080E925737D7DC56A1437C72236C60C17678642450F0EEC178B95A1465BA5B002802D467A03B71506D7C9F69380FBB0ADE8AA346D5FDD4E37D4E22EB193986298AFC4C9BF6B5DDAF060DA0E30CF2219DE173AF04E16678A21B94897769 |
||
Will use certificate from 'mycert.pem' to verify signature |
Will use certificate from 'mycert.pem' to verify signature |
||
Issuer: O=MyOrg, ST=MyCity, C=BE |
Issuer: O=MyOrg, ST=MyCity, C=BE |
||
Line 152: | Line 203: | ||
Signature is valid: true |
Signature is valid: true |
||
</pre> |
</pre> |
||
+ | |||
+ | ===Performances=== |
||
+ | Measured on a Nexus S, stats over 20 runs: |
||
+ | |||
+ | With CPU locked at 1000MHz (CPU sceduler = performance) and idle |
||
+ | * Resp to SelectApp: 32ms (std. dev. 11%) |
||
+ | * Resp to VerifyPIN(*): 296ms (std. dev. 3%) |
||
+ | * Resp to GetSign(**): 67ms (std.dev. 18%) |
||
+ | |||
+ | With CPU locked at 1000MHz (CPU sceduler = performance) and busy with infinite loop |
||
+ | * Resp to SelectApp: 63ms (std. dev. 15%) |
||
+ | * Resp to VerifyPIN(*): 600ms (std. dev. 4%) |
||
+ | * Resp to GetSign(**): 100ms (std.dev. 20%) |
||
+ | |||
+ | (*) : the phone does a PBKDF2 on the PIN : 5000 x SHA1 hashes |
||
+ | <br>(**) : the phone does a 1024-bit RSA signature |
||
+ | ===TypeB=== |
||
+ | If you want to emulate a TypeB card rather than a TypeA card, simply edit the app sources virtual-pki-card/se-emulator and replace all occurrences of PCDA into PCDB and PcdA into PcdB. |
||
+ | <source lang=bash> |
||
+ | $ grep -i -n -r pcda . |
||
+ | ./src/org/nick/se/emulator/MainActivity.java:40: private static final String TECH_ISO_PCDA = "android.nfc.tech.IsoPcdA"; |
||
+ | ./src/org/nick/se/emulator/MainActivity.java:92: techLists = new String[][] { { "android.nfc.tech.IsoPcdA" } }; |
||
+ | ./src/org/nick/se/emulator/MainActivity.java:174: if (!techList.contains(TECH_ISO_PCDA)) { |
||
+ | ./src/org/nick/se/emulator/MainActivity.java:175: Log.e(TAG, "IsoPcdA not found in tech list"); |
||
+ | ./src/org/nick/se/emulator/MainActivity.java:179: TagWrapper tw = new TagWrapper(tag, TECH_ISO_PCDA); |
||
+ | ./res/xml/filter_nfc.xml:4: <tech>android.nfc.tech.IsoPcdA</tech> |
||
+ | </source> |
||
+ | |||
+ | ==Example using [https://www.lateralsecurity.com/tools Lateral Security tools]== |
||
+ | cf their NFCCAPTURE |
||
+ | |||
+ | ==Examples of MitM== |
||
+ | Of course once you can emulate a card you can also mount a MitM attack on ISO14443-4 cards: |
||
+ | * [http://sourceforge.net/projects/nfcproxy/ NFCProxy] |
||
+ | * [https://www.lateralsecurity.com/tools#NFCapture Lateral Security NFCCAPTURE] |
||
+ | |||
+ | =Since Android 4.4= |
||
+ | See [https://developer.android.com/guide/topics/connectivity/nfc/hce.html official description] |
||
+ | |||
+ | NFC card-emulation and Android 4.4 |
||
+ | * [http://randomoracle.wordpress.com/2013/12/02/nfc-card-emulation-and-android-4-4-part-i/ Part 1]: intro to card emulation |
||
+ | * [http://randomoracle.wordpress.com/2013/12/07/nfc-card-emulation-and-android-4-4-part-ii/ Part 2]: coexistence of several secure elements |
||
+ | * [http://randomoracle.wordpress.com/2013/12/12/nfc-card-emulation-and-android-4-4-part-iii/ Part 3]: how AID routing is used to create an open ecosystem |
||
+ | * [http://randomoracle.wordpress.com/2013/12/17/nfc-card-emulation-and-android-4-4-part-iv/ Part 4]: edge-cases of HCE and some differences from the embedded secure element |
||
+ | [http://repo.xposed.info/module/at.zweng.xposed.modifyaidrouting NFC Card-Emulation Catch-All Routing], a Xposed module to route all AIDs to your app. |
||
+ | |||
+ | =Security= |
||
+ | HCE vs embedded secure element by Cem Paya aka RandomOracle: |
||
+ | * [http://randomoracle.wordpress.com/2014/03/08/hce-vs-embedded-secure-element-comparing-risks-part-i/ Part 1: comparing risks] |
||
+ | * [http://randomoracle.wordpress.com/2014/03/18/hce-vs-embedded-secure-element-tamper-resistance-part-ii/ Part 2: tamper resistance] |
||
+ | * [http://randomoracle.wordpress.com/2014/04/03/hce-vs-embedded-secure-element-attack-surface-part-iii/ Part 3: attack surface] |
||
+ | * [https://randomoracle.wordpress.com/2014/04/21/hce-vs-embedded-secure-element-taking-android-out-of-tcb-part-iv/ Part 4: taking Android out of TCB] |
||
+ | [http://www.ul-ts.com/downloads/whitepapers/finish/6-whitepapers/289-hce-security-implications HCE security implications] whitepaper (pdf) |
Latest revision as of 20:08, 9 December 2015
Software Card Emulation on Android
Before Android 4.4
Readings
- Software Card Emulation in NFC-enabled Mobile Phones: Great Advantage or Security Nightmare? (pdf) by Michael Roland, IWSSI2012
- Emulating a PKI smart card with CyanogenMod 9.1 by Nikolay Elenkov
- SimplyTapp by Doug Yeager
Requirements
Android phone with a PN544 NFC chipset
Limitations
ISO14443-4A
- Random UID (starting with "08")
- SAK (SEL_RES): 60
- Compliant with ISO/IEC 14443-4
- Compliant with ISO/IEC 18092
- ATS: 78 33 88 00
- Max Frame Size accepted by PICC: 256 bytes
- Bit Rate Capability:
- PICC to PCD, DS=2, bitrate 212 kbits/s supported
- PICC to PCD, DS=4, bitrate 424 kbits/s supported
- PCD to PICC, DR=2, bitrate 212 kbits/s supported
- PCD to PICC, DR=4, bitrate 424 kbits/s supported
- Frame Waiting Time: 77.33 ms
- Start-up Frame Guard Time: 77.33 ms
- Node Address not supported
- Card IDentifier not supported
- Corresponding ATR: 3B80800101
ISO14443-4B
- Random PUPI
- Application Data: 00 00 00 00
- Protocol Info: 33 81 84
- Bit Rate Capability:
- PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported
- PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported
- PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported
- PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported
- Maximum frame sizes: 256 bytes
- Protocol types supported: ISO/IEC 14443-4
- Frame Waiting Time: 77.33 ms
- Bit Rate Capability:
FeliCa
The PN544 chip is also able to emulate FeliCa even if it's not (yet) accessible from Android API but this means if an external FeliCa reader is polling the phone it can get something like FeliCa target:
- Random ID (NFCID2): 01 fe nn nn nn nn nn nn
- Parameter (PAD): c0 c1 c2 c3 c4 c5 c6 c7
- System Code (SC): 0f ab
Delay
On a Nexus S locked at 1000MHz and idle, a delay of about 30ms is still measured. It goes to 60ms if CPU is busy or occasionally even higher under "on demand" CPU scheduler.
Installation
Software CE is not possible yet on stock Android but patches have been made for CyanogenMod and they are integrated in the official release since v10.1.
So, easiest is to install cyanogenmod 10.1 (or more recent if available), see instructions
Example of PKI smartcard
This example is taken from this very interesting post and its source code, adapted for CyanogenMod 10.1 and compiled under Linux in command line.
It's a small example emulating a card able to do a PIN verify then a signature, a bit like some eIDs.
Compile application
Following instructions how to compile Android app in command line
git clone https://github.com/nelenkov/virtual-pki-card
cd virtual-pki-card/se-emulator
JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.26/
ANDROID_HOME=/your_path_to/android-sdk-linux_x86/
PACKAGE=org.nick.se.emulator
PACKAGE_SLASH=${PACKAGE//.//}
DEV_HOME=$(pwd)
TARGET=android-17
mkdir -p $DEV_HOME/obj
mkdir -p $DEV_HOME/bin
mkdir -p $DEV_HOME/lib
Create dummy keystore
$JAVA_HOME/bin/keytool -genkeypair \
-validity 10000 \
-dname "CN=company name,
OU=organisational unit,
O=organisation,
L=location,
S=state,
C=country code" \
-keystore $DEV_HOME/AndroidTest.keystore \
-storepass password \
-keypass password \
-alias AndroidTestKey \
-keyalg RSA \
-v
Create R.java
$ANDROID_HOME/platform-tools/aapt package -v -f -m \
-S $DEV_HOME/res -J $DEV_HOME/src -M $DEV_HOME/AndroidManifest.xml \
-I $ANDROID_HOME/platforms/$TARGET/android.jar || exit 1
Compile Java
$JAVA_HOME/bin/javac -verbose -d $DEV_HOME/obj \
-classpath "$ANDROID_HOME/platforms/$TARGET/android.jar:$DEV_HOME/obj" \
-sourcepath $DEV_HOME/src \
$DEV_HOME/src/$PACKAGE_SLASH/*.java || exit 1
Create DEX
$ANDROID_HOME/platform-tools/dx --dex --verbose \
--output=$DEV_HOME/bin/classes.dex \
$DEV_HOME/obj $DEV_HOME/lib || exit 1
Create APK
$ANDROID_HOME/platform-tools/aapt package -v -f \
-S $DEV_HOME/res -M $DEV_HOME/AndroidManifest.xml \
-I $ANDROID_HOME/platforms/$TARGET/android.jar \
-F $DEV_HOME/bin/AndroidTest.unsigned.apk \
$DEV_HOME/bin || exit 1
Sign APK
$JAVA_HOME/bin/jarsigner -verbose \
-keystore $DEV_HOME/AndroidTest.keystore \
-storepass password \
-keypass password \
-signedjar $DEV_HOME/bin/AndroidTest.signed.apk \
$DEV_HOME/bin/AndroidTest.unsigned.apk \
AndroidTestKey || exit 1
Zip-align APK
$ANDROID_HOME/tools/zipalign -v -f 4 \
$DEV_HOME/bin/AndroidTest.signed.apk \
$DEV_HOME/bin/AndroidTest.apk || exit 1
Install application
sudo adb install $DEV_HOME/bin/AndroidTest.apk
Create certificate
As this example is using a certificate to sign data, we need to create it.
cd virtual-pki-card
mkdir cert
cd cert
Create a template mykey.conf:
[ req ]
default_bits = 1024
distinguished_name = req_distinguished_name
prompt = no
output_password = 1234
[ req_distinguished_name ]
C = BE
ST = MyCity
O = MyOrg
Create certificate:
openssl req -new -x509 -keyout mykey.pem -out mycert.pem -config mykey.conf
openssl pkcs12 -export -in mycert.pem -inkey mykey.pem -passin pass:1234 -passout pass: > mykey.pfx
Install it:
sudo adb push mykey.pfx /sdcard/
cp mycert.pem ../se-pki-client/
On the phone:
Run application "PKI Applet Emulator"
- Install PKCS#12
- no passwd
- if needed create a lock PIN on the phone (to be able to store certs)
- choose cert: select this one, ok
- Set PIN=1234
If reading cert fails, check in CyanogenMod developer options that "Protect USB storage" is not activated.
Storing certs require that you defined a screen lock PIN too, do it if needed.
Reader application
Compile:
cd se-pki-client
javac src/org/nick/sepkiclient/Main.java
Execute:
java -cp src org.nick.sepkiclient.Main 1234 mycert.pem
Place phone/card on reader to start --> 00A4040006A0000000010101 <-- 9000 --> 800100000431323334 <-- 9000 --> 80020000087369676E206D6521 <-- 7C19AAE869DD6C2A9C4AAB98E65FEFDF88C0764EDDAD1BE660BBA220237BA7F4D46B08080E925737D7D ... Got signature from card: 7C19AAE869DD6C2A9C4AAB98E65FEFDF88C0764EDDAD1BE660BBA220237BA7F4D46B08080E925737D7D ... Will use certificate from 'mycert.pem' to verify signature Issuer: O=MyOrg, ST=MyCity, C=BE Subject: O=MyOrg, ST=Mycity, C=BE Not Before: Thu Sep 05 11:46:55 CEST 2013 Not After: Sat Oct 05 11:46:55 CEST 2013 Signature is valid: true
Performances
Measured on a Nexus S, stats over 20 runs:
With CPU locked at 1000MHz (CPU sceduler = performance) and idle
- Resp to SelectApp: 32ms (std. dev. 11%)
- Resp to VerifyPIN(*): 296ms (std. dev. 3%)
- Resp to GetSign(**): 67ms (std.dev. 18%)
With CPU locked at 1000MHz (CPU sceduler = performance) and busy with infinite loop
- Resp to SelectApp: 63ms (std. dev. 15%)
- Resp to VerifyPIN(*): 600ms (std. dev. 4%)
- Resp to GetSign(**): 100ms (std.dev. 20%)
(*) : the phone does a PBKDF2 on the PIN : 5000 x SHA1 hashes
(**) : the phone does a 1024-bit RSA signature
TypeB
If you want to emulate a TypeB card rather than a TypeA card, simply edit the app sources virtual-pki-card/se-emulator and replace all occurrences of PCDA into PCDB and PcdA into PcdB.
$ grep -i -n -r pcda .
./src/org/nick/se/emulator/MainActivity.java:40: private static final String TECH_ISO_PCDA = "android.nfc.tech.IsoPcdA";
./src/org/nick/se/emulator/MainActivity.java:92: techLists = new String[][] { { "android.nfc.tech.IsoPcdA" } };
./src/org/nick/se/emulator/MainActivity.java:174: if (!techList.contains(TECH_ISO_PCDA)) {
./src/org/nick/se/emulator/MainActivity.java:175: Log.e(TAG, "IsoPcdA not found in tech list");
./src/org/nick/se/emulator/MainActivity.java:179: TagWrapper tw = new TagWrapper(tag, TECH_ISO_PCDA);
./res/xml/filter_nfc.xml:4: <tech>android.nfc.tech.IsoPcdA</tech>
Example using Lateral Security tools
cf their NFCCAPTURE
Examples of MitM
Of course once you can emulate a card you can also mount a MitM attack on ISO14443-4 cards:
Since Android 4.4
NFC card-emulation and Android 4.4
- Part 1: intro to card emulation
- Part 2: coexistence of several secure elements
- Part 3: how AID routing is used to create an open ecosystem
- Part 4: edge-cases of HCE and some differences from the embedded secure element
NFC Card-Emulation Catch-All Routing, a Xposed module to route all AIDs to your app.
Security
HCE vs embedded secure element by Cem Paya aka RandomOracle:
- Part 1: comparing risks
- Part 2: tamper resistance
- Part 3: attack surface
- Part 4: taking Android out of TCB
HCE security implications whitepaper (pdf)