Mobile Payments on Android Using Host Card Emulation (HCE)

Mobile Payments on Android Using Host Card Emulation (HCE)

VIDEO of this Presentation at Droidcon NYC 2015: https://www.youtube.com/watch?v=0bXg30qA7EA

Overview: Learn how Host Card Emulation (HCE) works on Android to enable contactless payments. This is shown by following along with an example application, Handstand Pay (https://github.com/handstandsam/HandstandPay). This example app uses Visa MSD data that was the first form of contactless payments. This presentation also overviews the latest cloud-based secure element HCE solutions using a tokenization provider.

Presented at:
* Droidcon NYC 2015 - August 27, 2015
* AnDevCon Boston 2015 - July 31, 2015

5701f31a8433a22ae736282de8d08cd6?s=128

Sam Edwards

August 27, 2015
Tweet

Transcript

  1. MOBILE PAYMENTS ON ANDROID Sam Edwards @HandstandSam https://github.com/HandstandSam/HandstandPay

  2. NFC NEAR FIELD COMMUNICATION

  3. [VIDEO] WHAT IS NFC?

  4. PRIMARY NFC USES ON ANDROID Static NFC Tags Android Beam

    Payments
  5. NFC PAYMENTS ON ANDROID • NFC on Android 2.3 (December

    2010) • Secure hardware element required • Restricted access to secure element because of manufacturers and carriers • HCE on Android 4.4 (October 2013) • HCE API released • Secure element no longer required 5
  6. HCE SECURE ELEMENT SECURE HARDWARE ELEMENT VS HCE

  7. + = 4.4+ EXACT VIRTUAL REPRESENTATION OF A SMART CARD

    USING ONLY SOFTWARE Host Card Emulation on
  8. 57.4% PHONES ON ANDROID 4.4+ GOOGLE STATS AS OF AUGUST

    3, 2015 http://developer.android.com/about/dashboards/index.html
  9. • Apple Pay exclusively • Secure element only • Open

    NFC and HCE APIs • HCE and/or secure element • Depends on hardware, OS & carrier restrictions ANDROID > IOS
  10. OPPORTUNITY

  11. US EMV MANDATE - OCTOBER 2015 MSD MAGNETIC STRIPE DATA

    EMV EUROPASS MASTERCARD VISA
  12. US EMV MANDATE - OCTOBER 2015 INC “The party, either

    the issuer or merchant, who does not support EMV, assumes liability for counterfeit card transactions.” http://www.paymentsleader.com/will-retailers-be-ready-for-emv-by-oct-2015/
  13. MORE TERMINALS, MORE PAYMENTS • http://www.bloomberg.com/news/2014-09-10/mobile-payments-forecast-hazy-with-a-chance-of-apple.html

  14. BIGGEST PLAYERS IN US CONTACTLESS PAYMENTS

  15. • Gets all the press • Apple controlled user experience

    • Secure element • Contactless & in-app payments • Apple hardware required
  16. • US Beta started Tuesday & Launch on September 28th

    • Contactless Terminals • Secure element • Magstripe Terminals • Using LoopPay Technology
  17. [VIDEO] HOW DOES LOOP PAY WORK?

  18. • Google Wallet • Virtual MasterCard, charges to cards on

    file • Contactless and in-app payments • Android Pay • Requires card issuer integration • Tokenized version of original card • Contactless and in-app payments HCE IMPLEMENTATIONS
  19. HANDSTAND PAY \ https://github.com/handstandsam/HandstandPay

  20. [VIDEO] HCE IN ACTION • Vending Machine • Walgreens •

    Panera • Duane Reade • Jet Blue [VIDEO] USING HANDSTAND PAY AT: VENDING MACHINE, WALGREENS, PANERA BREAD, DUANE READE, JET BLUE AIRLINES
  21. SOME LESSONS LEARNED • Everyone calls it “Apple Pay” •

    Single tap? Double tap? • Airplane Mode disables NFC as well • Employees aren’t trained on contactless
  22. PAYMENT APPS ARE HEAVY LIFTING Custom • Terminal communication •

    User experience • Payment credential management
  23. • Must Extend • android.nfc.cardemulation.HostApduService • Purpose • Process and

    respond to terminal commands • Runs When • Device is tapped on terminal and you are the default for an AID HCE REQUIRES A HostApduService HostApduService
  24. HostApduService @TargetApi(Build.VERSION_CODES.KITKAT)
 public class HandstandApduService extends HostApduService {
 
 @Override


    public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
 
 byte[] responseApdu = …;
 return responseApdu;
 } @Override
 public void onDeactivated(int reason) { } }
  25. HostApduService in AndroidManifest.xml <service
 android:name=".apdu.HandstandApduService"
 android:exported="true"
 android:permission="android.permission.BIND_NFC_SERVICE">
 <intent-filter>
 <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"

    />
 
 <category android:name="android.intent.category.DEFAULT" />
 </intent-filter>
 
 <meta-data
 android:name="android.nfc.cardemulation.host_apdu_service"
 android:resource="@xml/apdu_config" />
 </service>
  26. HostApduService CONFIGURATION <host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
 android:apduServiceBanner="@drawable/front"
 android:description="@string/apdu_description"
 android:requireDeviceUnlock="false">
 
 <aid-group
 android:category="payment"


    android:description="@string/aid_group_description">
 <aid-filter
 android:name="325041592E5359532E4444463031"
 android:description="@string/aid_ppse_description" />
 <aid-filter
 android:name="A0000000031010"
 android:description="@string/aid_visa_description" /> </aid-group>
 
 </host-apdu-service>
  27. DEFAULT PAYMENT APP IN ANDROID SETTINGS [VIDEO]

  28. DEFAULT PAYMENT APP [VIDEO]

  29. DEFAULT PAYMENT APP public static void ensureSetAsDefaultPaymentApp(Activity context) {
 NfcAdapter

    nfcAdapter = NfcAdapter.getDefaultAdapter(context);
 CardEmulation cardEmulation = CardEmulation.getInstance(nfcAdapter); ComponentName componentName = new ComponentName(context, HandstandApduService.class);
 boolean isDefault = cardEmulation.isDefaultServiceForCategory(componentName, CardEmulation.CATEGORY_PAYMENT);
 
 if (!isDefault) {
 Intent intent = new Intent(CardEmulation.ACTION_CHANGE_DEFAULT);
 intent.putExtra(CardEmulation.EXTRA_CATEGORY, CardEmulation.CATEGORY_PAYMENT);
 intent.putExtra(CardEmulation.EXTRA_SERVICE_COMPONENT, componentName);
 context.startActivityForResult(intent, REQUEST_CODE_DEFAULT_PAYMENT_APP);
 }
 }
  30. FAVOR FOREGROUND APP LOLLIPOP 5.0+ [VIDEO]

  31. FAVOR FOREGROUND APP FROM ACTIVITY @Override
 public void onResume() {


    super.onResume();
 if (isLollipopOrHigher()) { setAsPreferredHceService();
 }
 IntentFilter paymentSentIntentFilter = new IntentFilter(HandstandApduService.PAYMENT_SENT);
 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(PayActivity.this);
 lbm.registerReceiver(animationBroadcastReceiver, paymentSentIntentFilter);
 creditCardView.updateValues(); }
 @Override
 public void onPause() {
 super.onPause();
 if (isLollipopOrHigher()) {
 unsetAsPreferredHceService();
 }
 IntentFilter paymentSentIntentFilter = new IntentFilter(HandstandApduService.PAYMENT_SENT);
 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(PayActivity.this);
 lbm.unregisterReceiver(animationBroadcastReceiver);
 }
  32. FAVOR FOREGROUND APP @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void setAsPreferredHceService() {
 boolean allowsForeground

    = cardEmulation.categoryAllowsForegroundPreference(CardEmulation.CATEGORY_PAYMENT);
 if (allowsForeground) {
 ComponentName hceComponentName = new ComponentName(context, HandstandApduService.class);
 cardEmulation.setPreferredService(PayActivity.this, hceComponentName);
 } }
 
 @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void unsetAsPreferredHceService() {
 boolean allowsForeground = cardEmulation.categoryAllowsForegroundPreference(CardEmulation.CATEGORY_PAYMENT);
 if (allowsForeground) {
 ComponentName hceComponentName = new ComponentName(context, HandstandApduService.class);
 cardEmulation.unsetPreferredService(PayActivity.this);
 }
 }
  33. HOW HANDSTAND PAY WORKS HostApduService Pay Activity Send Broadcast PAYMENT_SENT

    Start Activity
  34. START ACTIVITY private void startPaymentActivityInBackgroundThread() {
 new Runnable() {
 @Override


    public void run() { //Start Payment Activity in background thread for HostApduService performance
 Intent intent = new Intent(getApplicationContext(), PayActivity.class);
 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
 getApplicationContext().startActivity(intent); }
 }.run();
 }
  35. SEND LOCAL BROADCAST FROM SERVICE @TargetApi(Build.VERSION_CODES.KITKAT)
 public class HandstandApduService extends

    HostApduService { 
 @Override
 public void onDeactivated(int reason) {
 isProcessing = false;
 Context context = getApplicationContext();
 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context); //Send local broadcast message telling the app that the payment has been sent
 lbm.sendBroadcast(new Intent(PAYMENT_SENT));
 } }
  36. RECEIVE LOCAL BROADCAST IN ACTIVITY public class PayActivity extends Activity

    { @Override
 public void onResume() { IntentFilter paymentSentIntentFilter = new IntentFilter(HandstandApduService.PAYMENT_SENT);
 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(PayActivity.this);
 lbm.registerReceiver(broadcastReceiver, paymentSentIntentFilter); } }
  37. APDU TERMINAL COMMUNICATION

  38. WAITING… APDU TERMINAL COMMUNICATION

  39. COMMAND 1: SELECT PPSE • Do you support Proximity Payment

    Service Environment (PPSE)? • 00A404000E325041592E5359532E444446303100
 • Yes, and we only support Visa. • F23840E325041592E5359532E4444463031A511BF0 C0E610C4F07A00000000310108701019000 http://blog.simplytapp.com/2014/01/host-card-emulation-series-swipeyours.html
  40. STEP 2: SELECT AID • The terminal asks us to

    use Visa, because that’s what we told them to do. • 00A4040007A000000003101000
 • We support Visa-MSD. • 6F1E8407A0000000031010A513500B5649534120 4352454449549F38039F66029000 http://blog.simplytapp.com/2014/01/host-card-emulation-series-swipeyours.html
  41. STEP 3: GET PROCESSING OPTIONS • Get Processing Options (GPO)

    • 80A80000048302800000
 • Tell the terminal we only support Visa-MSD • 80060080080101009000 http://blog.simplytapp.com/2014/01/host-card-emulation-series-swipeyours.html
  42. STEP 4: READ RECORD • Terminal requests payment data. •

    00B2010C00
 • Returns the Magstripe “Track 2”information. • 701257104941594325785315D2406121100000409 000 http://blog.simplytapp.com/2014/01/host-card-emulation-series-swipeyours.html
  43. HANDSTAND PAY VISA MAGSTRIPE DATA %B4941594325785315^YOU/A GIFT FOR^24061211000000040000000? ;4941594325785315=240612110000040?

  44. WARNING HANDSTAND PAY HAS NO SECURITY

  45. ON DEVICE SECURITY • Android 4.4+ • Username/Password • Device

    Administration • Android M • New Fingerprint Sensor API • android.permission.USE_FINGERPRINT • FingerprintManager.authenticate() • Confirm Credential • Make sure user unlocked phone in last __ minutes http://developer.android.com/guide/topics/admin/device-admin.html https://developer.android.com/preview/api-overview.html#fingerprint-authentication
  46. CLOUD-BASED SECURITY • Tokenization • Replace the PAN with limited

    use data that passes seamlessly through the payment system. • Keys • Expire quickly preventing their misuse. • Device Fingerprinting • Validate the phone. Data analysis provides real-time transaction assessment to identify unusual activity. • Transaction Risk Analysis • The more data used to measure and analyze, the better the overall security.
  47. STATIC TOKENIZATION ACTUAL 4941 1111 1111 1111 TOKENIZED HAPPENS ONCE

  48. DYNAMIC TOKENIZATION ACTUAL TOKENIZED 4941 1111 1111 1111 HAPPENS EVERY

    TRANSACTION 4941 1111 1111 1112 4941 1111 1111 1113
  49. SEMI-DYNAMIC TOKENIZATION DPAN (TOKEN) 4941 1111 1111 1111 ACTUAL Rotating

    Keys 4941 1111 1111 1111
  50. HCE CONTACTLESS PAYMENT APDU Containing Cryptogram Send byte [] $

    DPAN (TOKEN) 4941 1111 1111 1111 Key
  51. HCE TOKENIZATION PROVIDERS

  52. WHAT CAN I DO NOW? • Get a Visa Prepaid

    Card (or use your own at your own risk) • Try out Handstand Pay, fork it on Github and hack it • Check out Simply Tapp’s Mobile SDK for cloud based payments