2 poin oleh GN⁺ 2023-10-29 | 1 komentar | Bagikan ke WhatsApp
  • Karena Seattle Public Library dan King County Library System ingin mengurangi kartu plastik, penulis akhirnya harus menangani sendiri struktur JSON, gambar, dan tanda tangan untuk pass Wallet di iPhone
  • Wallet hanya mendukung QR code, PDF417, Aztec Code, dan Code 128, sehingga Codabar pada kartu perpustakaan tidak bisa dimasukkan sebagai barcode bawaan; barcode untuk pemindaian akhirnya disiasati lewat gambar
  • Pass harus ditandatangani dengan kunci yang dipercaya Apple, tetapi alih-alih membayar keanggotaan Apple Developer 99 dolar per tahun, penulis menemukan dan memakai sertifikat serta kunci dari aplikasi pass iOS yang bisa membuat pass secara offline
  • Dengan menggabungkan tata letak storeCard, logo untuk tiap resolusi, Codabar strip.png, dan entri PKBarcodeFormatCode128 kosong, penulis bisa menampilkan barcode gambar di layar sambil tetap memicu perilaku peningkatan kecerahan layar di iOS
  • .pkpass yang selesai dapat dibuat lewat pembuatan manifest, penandatanganan openssl smime, dan pengemasan ZIP; meski belum diuji di perpustakaan sungguhan, pemindai terpisah bisa membaca barcode di layar ponsel

Tujuan: memakai barcode perpustakaan tanpa kartu plastik

  • Seattle Public Library dan King County Library System menerbitkan kartu plastik dengan barcode tercetak yang terhubung ke akun peminjaman
  • Per 2023, sebagian besar fungsi di perpustakaan Seattle bersifat swalayan, dan biasanya barcode perpustakaan bisa dimasukkan secara manual
  • Meski begitu, jauh lebih praktis jika bisa langsung menampilkan barcode, jadi tujuannya adalah menaruhnya di aplikasi Wallet iPhone alih-alih membawa kartu plastik yang hampir tidak pernah dipakai di dompet

Pass Wallet terdiri dari JSON, gambar, dan tanda tangan

  • Aplikasi Wallet sekarang menangani kartu pembayaran, identitas, kunci, dan lain-lain, tetapi saat Passbook dirilis pada 2012, aplikasi ini hanya mengelola “pass”
  • Menurut dokumentasi pass Apple, pass adalah file ZIP mandiri yang bisa didistribusikan lewat email atau web, dengan isi JSON dan PNG di dalamnya
  • Komponen inti file .pkpass sederhana
    • pass.json: menjelaskan isi pass selain gambar
    • manifest.json: daftar checksum SHA-1 untuk file-file lain
    • signature: tanda tangan S/MIME atas isi manifest.json
    • file gambar yang didukung

Ketidakdukungan Codabar menjadi hambatan pertama

  • Pass Wallet hanya mendukung empat jenis barcode
    • QR code
    • PDF417
    • Aztec Code
    • Code 128
  • Kartu perpustakaan memakai format Codabar, yang umum digunakan di perpustakaan
  • Mungkin saja pemindai barcode perpustakaan mendukung barcode linear lain, tetapi satu-satunya format yang bisa dianggap pasti bekerja di semua cabang adalah Codabar
  • Akhirnya, alih-alih memakai fungsi barcode bawaan Wallet, penulis harus membuat gambar Codabar yang bisa dipindai dan memasukkannya ke dalam pass

Masalah sertifikat tanda tangan pass

  • Pass Wallet memerlukan tanda tangan kriptografis, dan harus ditandatangani dengan kunci yang dipercaya oleh salah satu otoritas sertifikat Apple
  • Jika dipakai untuk pembaruan otomatis pass oleh vendor, seperti perubahan gate atau kursi pada boarding pass, persyaratan tanda tangan sampai batas tertentu masuk akal
  • Pengembang Apple relatif mudah mendapatkan kunci penandatanganan pass, tetapi penulis tidak ingin membayar 99 dolar per tahun hanya untuk pekerjaan ini

Mengapa aplikasi pembuat pass yang sudah ada tidak cocok

  • Ada beberapa aplikasi desain pass yang dibuat oleh orang-orang yang sudah menjadi pengembang Apple, tetapi tidak memberi tingkat kontrol yang dibutuhkan
  • Kontrol ukuran logo

    • Apple mengizinkan tinggi maksimum 50 piksel independen-perangkat untuk logo di kiri atas pass
    • Logo persegi di sisi kanan teks paling pas jika tingginya sekitar 40px
    • Pengembang harus menyediakan logo.png, logo@2x.png, dan logo@3x.png masing-masing, tetapi aplikasi biasanya hanya mengizinkan pemilihan satu logo tanpa kontrol skala
  • Perilaku kecerahan layar

    • Saat membuka pass dengan barcode yang didukung, layar akan menjadi lebih terang untuk membantu kontras bagi pemindai
    • Agar iOS tetap mencerahkan layar tanpa menampilkan barcode yang sebenarnya tidak berfungsi, penulis perlu mengubah pass.json secara langsung
    • Beberapa aplikasi gratis yang bisa diunduh juga membatasi jumlah pass yang dapat disimpan ke Wallet dan meminta pembayaran

Mencari kunci penandatanganan dari aplikasi pembuat offline

  • Penulis mengunduh beberapa aplikasi pembuat pass gratis versi awal dan memeriksa apakah pass bisa dibuat secara offline
  • Dari pengujian dalam mode pesawat dengan Wi-Fi dimatikan, setidaknya ada satu aplikasi yang bisa membuat pass secara offline
  • Nama aplikasinya sengaja tidak disebutkan untuk menghindari pencabutan kunci
  • Prosesnya ternyata lebih sederhana dari dugaan
    • Karena aplikasi iOS bisa dijalankan di Mac Apple silicon, penulis mengunduh aplikasinya ke Mac
    • Di dalam bundle aplikasi iOS yang dibungkus, penulis menemukan file .p12 yang mencolok
    • File PKCS#12 memerlukan kata sandi impor, jadi penulis menjalankan strings pada biner utama untuk mencari string yang tampak seperti kata sandi
  • Saat memeriksa informasi sertifikat dengan openssl pkcs12, issuer yang muncul adalah Apple Worldwide Developer Relations Certification Authority
  • Rantai sertifikat juga dibutuhkan; sertifikat intermediate mungkin ada di dalam bundle aplikasi dan juga bisa diunduh lewat URL pada field ekstensi X.509

Menyusun tata letak pass

  • Gaya pass harus memilih salah satu dari boarding pass, coupon, event ticket, generic, atau store card
  • Untuk memasukkan gambar horizontal besar, dibutuhkan tata letak yang mendukung gambar strip
    • Pilihannya adalah coupon, event ticket, dan store card
    • Karena paling mirip dengan kartu perpustakaan fisik, penulis memilih store card
  • pass.json berisi nilai berikut
    • passTypeIdentifier
    • teamIdentifier
    • formatVersion
    • serialNumber
    • organizationName
    • logoText
    • description
    • storeCard
    • backgroundColor
    • foregroundColor
    • sharingProhibited
  • passTypeIdentifier dan teamIdentifier masing-masing harus cocok dengan field UID dan OU pada subject sertifikat Apple
  • Setiap pass yang dibuat dengan passTypeIdentifier yang sama memerlukan serialNumber unik
  • Gambar disiapkan sesuai kegunaannya
    • icon.png wajib ada, tetapi tidak ditampilkan di pass itu sendiri
    • logo.png adalah logo yang ditampilkan di kiri atas
    • Penulis membuat logo.png 40×40, logo@2x.png 80×80, dan logo@3x.png 120×120
    • logo@3x.png disalin menjadi icon.png
    • Barcode yang sudah dibuat sebelumnya dimasukkan ke strip.png

Membuat gambar barcode Codabar

  • iOS akan menskalakan dan memotong strip.png agar pas dengan kotak di layar perangkat, jadi tidak perlu membuat tiga versi strip.png untuk tiap resolusi
  • Kedua kartu perpustakaan memakai A dan D sebagai simbol awal dan akhir
  • Simbol awal dan akhir paling mudah dipastikan dengan pemindai barcode; jika tidak ada, bisa dibandingkan secara visual dengan tabel encoding Codabar di Wikipedia
  • Tidak banyak generator Codabar siap pakai yang praktis dipakai online, tetapi formatnya sendiri cukup mudah diimplementasikan
  • Pada prototipe, penulis memakai library Barcoders untuk Rust untuk membuat SVG, lalu menyesuaikannya dan mengekspor ke PNG
  • Tata letak akhir ditentukan dengan mempertimbangkan keterbacaan pemindaian dan tampilan iOS yang mengecilkan gambar
    • Tinggi barcode ditetapkan sebesar dua kali jumlah total simbol termasuk simbol awal dan akhir
    • Misalnya, nomor barcode 13 digit berarti ada 15 simbol, jadi tingginya dibuat 30 unit
    • Sebelum awal dan setelah akhir masing-masing diberi quiet space 15 unit
    • Di atas dan bawah barcode masing-masing diberi padding 50 unit
    • Tiap unit diperbesar menjadi 8 piksel agar iOS selalu mengecilkan gambar
    • Pada contoh barcode 15 simbol, tinggi gambar akhir menjadi 1040 piksel dan tinggi barcode itu sendiri 240 piksel
  • Penulis membuat skrip shell 69 baris yang menghasilkan BMP Codabar dengan tata letak tersebut lalu mengubahnya ke PNG dengan sips
  • Jika output skrip disimpan sebagai strip.png, maka gambar barcode untuk pass sudah siap

Menampilkan nomor barcode dan akal-akalan kecerahan layar

  • Nomor barcode ditampilkan di bawah barcode melalui secondaryFields
    • key: number
    • label: CARD NUMBER
    • value: nomor kartu
  • iOS akan mencerahkan layar saat pass dengan barcode dipilih untuk membantu pemindai
  • Hanya memakai Codabar dalam bentuk gambar tidak membuat iOS menganggap pass tersebut memiliki barcode
  • Penulis menyiasatinya dengan menetapkan entri barcode kosong di tingkat teratas pass.json
    • message berupa string kosong
    • format adalah PKBarcodeFormatCode128
    • messageEncoding adalah iso-8859-1
  • Dengan cara ini, barcode tidak ditampilkan di bagian bawah pass, tetapi iPhone tetap mencerahkan layar seolah-olah pass itu memiliki barcode

Penandatanganan dan pengemasan

  • Setelah semua file siap, manifest.json harus dibuat
  • manifest.json adalah objek dengan nama file sebagai key dan checksum SHA-1 sebagai value
  • Penulis menggabungkan sha1sum dan jq untuk membuat manifest bagi file PNG dan pass.json
  • Penandatanganan manifest dilakukan dengan perintah openssl smime
    • sertifikat penandatangan
    • private key
    • sertifikat intermediate Apple WWDR
    • input manifest.json
    • output signature
  • Opsi -attime pada openssl smime bisa dipakai untuk menentukan waktu penandatanganan yang diinginkan
    • Nilai opsinya berupa UNIX epoch
    • Walaupun sertifikat yang didapat dari Apple atau yang ditemukan sudah kedaluwarsa, penandatanganan masih bisa dilakukan untuk waktu tersebut
  • Terakhir, file-file berikut dibungkus ke dalam ZIP untuk membuat .pkpass
    • gambar PNG
    • pass.json
    • manifest.json
    • signature

Hasil pengujian dan hal yang disayangkan

  • macOS memiliki alat pratinjau pass untuk memeriksa apakah pass valid dan secara umum tampil dengan benar
  • Jika tidak valid, error bisa dicari di Console.app
  • Alat pratinjau ini tidak 100% akurat, tetapi punya tombol untuk mengirim ke iPhone lewat iCloud
  • Pass yang sudah jadi masih belum diuji di perpustakaan sungguhan
  • Namun, pemindai barcode terpisah bisa membaca barcode di layar ponsel sama seperti pada kartu plastik asli
    • Hanya saja, hasilnya terbaca baik saat kecerahan layar dinaikkan ke maksimum
    • Ini lebih terang daripada tingkat kecerahan yang dipicu oleh trik barcode kosong
  • Bagus bahwa spesifikasi pass hampir tidak berubah selama 10 tahun, tetapi disayangkan bahwa untuk menandatangani pass PNG dan JSON yang tidak berbahaya tetap dibutuhkan keanggotaan Apple Developer 99 dolar per tahun
  • Beberapa fitur pass mungkin memang layak mensyaratkan tanda tangan, tetapi menurut penulis, pekerjaan yang dilakukan di sini seharusnya tidak membutuhkannya
  • Jika Apple menambahkan dukungan Codabar ke Wallet, sistem perpustakaan bisa mendukung kartu perpustakaan digital tanpa harus mengaudit apakah semua pemindai mendukung Code 128

1 komentar

 
GN⁺ 2023-10-29
Komentar Hacker News
  • Lain kali semoga juga membahas kartu ORCA. Seattle adalah salah satu pusat teknologi di Amerika Serikat, tetapi bukan hanya kereta bawah tanah/transportasi umumnya yang kurang bagus, secara teknologi juga tertinggal dibanding hampir semua transportasi umum di kota-kota besar yang pernah saya pakai
    Dibanding kota mana pun di Eropa, CDMX, atau Denver, semuanya jauh lebih maju daripada Seattle, dan secara pribadi saya rasa Denver yang paling bagus
    Salah satu lembaga yang mengoperasikan ORCA pernah menulis posting blog bahwa mereka akan menambahkan dukungan NFC ke aplikasi Android, tetapi posting itu sekarang sudah hilang, dan setelah beberapa tahun pun fitur itu masih belum ada

    • Beberapa hari lalu ada kabar bahwa Google Wallet akan segera mendukungnya: https://blog.google/products/google-pay/commute-around-the-w...
    • Sistem transportasi di daerah kami baru-baru ini menambahkan pembayaran tap, jadi sekarang bisa memakai kartu kredit apa pun, Apple Pay, atau Google Pay
      Selama memakai kartu yang sama, perpindahan moda, pass beberapa hari, dan hal semacam itu diproses dengan mulus, dan tarif yang tepat juga diterapkan otomatis, misalnya tidak menagih lagi setelah jumlah perjalanan tertentu dalam periode tertentu
    • Saya penasaran, untuk sebagian besar sistem transportasi umum, seberapa besar biaya untuk mempertahankan sistem penagihan tarif dibandingkan dengan pendapatan yang hilang jika diubah menjadi naik gratis
    • Ngomong-ngomong, bukankah ada cara untuk melakukan kloning kartu NFC dengan Android yang sudah di-root?
      Pintu kantor saya terbuka dengan kartu NFC, jadi saya sempat mencari apakah ini mungkin di iOS, dan kalau tidak salah Apple mengontrol perangkat keras NFC lebih ketat daripada PassKit biasa, jadi sepertinya sulit dilakukan lewat aplikasi umum
    • https://info.myorca.com/news/can-i-use-my-phone-to-pay-for-a...
      Katanya pembayaran tap akan hadir di ORCA pada 2023, jadi kalau itu benar, sekarang tinggal sekitar dua bulan lagi
      Karena Google juga menulis bahwa ORCA akan segera didukung di Google Wallet, saya cukup optimistis
  • Jika ada pengguna Android yang tidak suka karena Google Wallet tidak bisa memasukkan sembarang barcode seperti Apple Passbook, ada aplikasi hebat di F-Droid bernama Loyalty Card Keychain: https://f-droid.org/en/packages/protect.card_locker/
    Anda bisa memasukkan angka secara manual atau memindai barcode yang sudah ada, lalu menyimpannya dengan memilih salah satu dari berbagai format barcode, termasuk Codabar. Menekan item di layar utama aplikasi akan menampilkan barcode yang dihasilkan dan juga menaikkan kecerahan layar
    Mungkin karena selain menampilkan barcode aplikasi ini tidak melakukan banyak hal, aplikasinya juga terbuka sangat cepat. Fiturnya cuma satu, tetapi mungkin ini salah satu aplikasi favorit saya
    Belakangan sepertinya orang menyarankan memakai Catima; saya sempat mencobanya sebentar dan tampaknya sama sederhananya serta berbasis codebase yang sama

    • Di Apple, saya membuat ‘kartu’ dengan Pass4Wallet lalu mengimpornya ke Apple Wallet untuk dipakai
      Memang tidak praktis, tetapi tujuannya tercapai, dan kebijakan privasinya juga bagus
    • Ada juga aplikasi yang memungkinkan Anda memasukkan barcode yang diinginkan ke Google Wallet: https://play.google.com/store/apps/details?id=color.dev.com....
  • Saya tidak mengerti kenapa pass harus ditandatangani secara kriptografis, dan harus ditandatangani dengan kunci yang diketahui otoritas sertifikasi Apple. Untuk keperluan pembaruan seperti ini, sudah ada HTTPS yang didukung dengan baik
    Mungkin Apple ingin pass bisa diverifikasi bukan hanya saat diperbarui, tetapi juga secara offline di ponsel, namun tetap terasa aneh. Pelaku jahat bisa saja bukan memperbarui pass, melainkan langsung menggantinya sepenuhnya

    • Cukup dengan membiarkan pass awal menentukan kunci publik yang diizinkan untuk melakukan pembaruan
      Saya sama sekali tidak paham apakah mengaitkannya dengan akun pengembang Apple benar-benar membantu masalah pembaruan
      Satu-satunya alasan yang terpikir untuk syarat bahwa pihak tersebut harus disetujui Apple adalah penjualan tiket palsu. Tidak ada cara untuk mengetahui apakah berkas pkpass “tiket konser X” itu asli atau tidak, dengan atau tanpa syarat tersebut
      Mungkin ini upaya untuk menanganinya dengan membatalkan akun pengembang tersebut jika ada laporan penipuan, tetapi ini pun tidak terasa seperti solusi. Biaya akun pengembang kemungkinan jauh lebih murah daripada uang yang bisa dihasilkan dari penipuan sebelum ketahuan
  • Saya cukup meminta agar PNG barcode yang berisi nomor kartu perpustakaan dikirim ke email saya, lalu membukanya di Photos atau Gmail saat berdiri di depan kios untuk dipakai

    • Pass Wallet bisa menentukan rentang lokasi dan waktu kapan pass itu akan muncul sebagai “relevan”
      Dengan aplikasi MakePass saya membuat pass berisi kode membership StarBucks, dan ketika saya berada di dekat toko yang sering saya kunjungi, ponsel saya otomatis menyarankan pass StarBucks itu dari layar kunci
      Hal yang sama berlaku untuk tiket acara: jika lokasi dan rentang waktunya ditentukan, saat tiba di lokasi Anda tidak perlu repot mencari pass karena akan disarankan otomatis. Setelah acara selesai, pass itu tidak disarankan lagi dan dipindahkan ke bagian “Expired Passes” sehingga tidak memenuhi layar utama
      MakePass: https://pvieito.com
    • Saat membaca sekilas artikelnya, saya terus mencari kenapa dia tidak cukup memotret saja
  • Tulisannya bagus, tetapi bagian akhirnya adalah “saya masih belum benar-benar menguji pass ini di perpustakaan sungguhan”
    Saya paham ini proyek iseng, tetapi saya tidak mengerti kenapa dia tidak meluangkan 10 menit yang dibutuhkan untuk menguji solusi akhirnya sebelum membagikan hasilnya

    • Bagian itu membuat seluruh tulisan jadi kehilangan tenaga. Rasanya seperti, “Saya punya teori ilmiah hebat tentang kehilangan oksigen saat berlari. Memang saya belum mulai jogging sih, tapi…”
    • Pada akhirnya ini cuma sekumpulan piksel yang merepresentasikan barcode yang akan dipindai. Selama ditampilkan dengan benar, apa yang bisa salah?
    • Bisa jadi perpustakaannya tutup pada hari Sabtu
  • Saat membuat barcode, saya pribadi lebih suka pembuat barcode berbasis PostScript
    https://bwipp.terryburton.co.uk/

  • Masalah ini saya selesaikan dengan memotret kartu perpustakaan. Saat meminjam buku, cukup buka fotonya lalu arahkan ke pemindai

    • Saya menaruh gambar barcode itu di notifikasi berbasis lokasi, jadi saat pergi ke perpustakaan dekat rumah, notifikasinya akan muncul
    • Jika barcode-nya statis, foto saja sudah cukup. Keuntungan menyimpannya di Wallet tidak terlalu besar
      Saya menyimpan semua kartu identitas di galeri foto ponsel
  • Jika ingin melakukan hal serupa di Android, ada Catima di Google Play dan F-Droid. Mendukung berbagai jenis barcode
    https://catima.app/

    • Bisa juga memakai Google Pay atau Samsung Pay
  • Pemindai barcode 1 dimensi laser yang murah tidak bisa membaca barcode dari layar. Mungkin bisa kalau eInk
    Kartu keanggotaan supermarket yang sering saya datangi berbasis barcode, jadi agak merepotkan, tapi untungnya pembaca barcode meniru keyboard sehingga kodenya bisa langsung diketik dengan keyboard

    • Setahu saya, sistem lama tidak memindai dengan sensor gambar digital, melainkan membaca perubahan kecerahan pantulan dari area barcode hitam/putih menggunakan sinar laser yang berputar dan fotodioda sederhana
      Pemindai berbasis kamera tidak peduli apakah pencahayaan barcode berasal dari cahaya sekitar, LED bawaannya sendiri, atau layar bercahaya belakang, tetapi sistem berbasis laser bergantung pada pantulan cahayanya sendiri sehingga sama sekali tidak berfungsi pada layar dengan backlight aktif
      Saya penasaran apakah itu bekerja pada layar e-ink atau LCD pasif
    • Saya pernah membuat penampil barcode murah dengan Bluetooth MCU dan layar E-ink, dan semuanya berfungsi baik pada pemindai barcode khusus 1 dimensi
    • Setiap kali melihat pemindai genggam Costco membaca barcode keanggotaan yang dicetak sangat sempit dan kecil pada kartu anggota dengan begitu cepat dan mudah, saya selalu kagum
      Dari luar kelihatannya seperti tipe 2D garis merah sederhana, tapi tampaknya perangkat keras memang sangat berpengaruh
  • Saya просто menghafal nomor akun KCLS. Mungkin hanya butuh sekitar 30 detik untuk menghafalnya, meski tentu tiap orang berbeda, tapi menurut saya cara ini lebih cepat
    Setelah itu, alih-alih memindai barcode, cukup masukkan nomor akun, dan kemungkinan memakan waktu lebih sedikit daripada mengeluarkan ponsel dan menyiapkannya
    Saya tidak tahu apakah SPL juga bisa dengan cara yang sama. Saya tidak tinggal di Seattle jadi tidak bisa memastikannya

    • Kalau tidak ingin menghafalnya, simpan saja di pengelola kata sandi pilihan Anda