- Seattle Public Library और King County Library System के plastic cards कम करने के लक्ष्य के चलते, iPhone Wallet pass की JSON, image और signature संरचना को सीधे संभालना पड़ा
- Wallet केवल QR code, PDF417, Aztec Code और Code 128 ही support करता है, इसलिए library card के Codabar को default barcode के रूप में नहीं जोड़ा जा सका; असली scan के लिए barcode को image के तौर पर workaround किया गया
- pass को Apple द्वारा trusted key से sign करना जरूरी था, लेकिन सालाना 99 डॉलर वाली Apple Developer membership लेने के बजाय, offline generation कर सकने वाले iOS pass app में certificate और key ढूंढकर इस्तेमाल किए गए
storeCardlayout, अलग-अलग resolution के logos, Codabarstrip.png, और खालीPKBarcodeFormatCode128item को मिलाकर screen पर image barcode दिखाया गया, फिर भी iOS का screen brightness बढ़ाने वाला behavior कायम रखा गया- तैयार
.pkpassmanifest generation,openssl smimesignature, और ZIP packaging से बनाया जा सका; असली library test से पहले भी एक अलग scanner ने phone screen पर barcode पढ़ लिया
लक्ष्य: plastic card के बिना library barcode इस्तेमाल करना
- Seattle Public Library और King County Library System loan account से जुड़े barcode-printed plastic cards जारी करते हैं
- 2023 तक Seattle library की ज्यादातर सुविधाएं self-service हैं, और आमतौर पर library barcode manually enter किया जा सकता है
- फिर भी barcode तुरंत दिखाना कहीं ज्यादा सुविधाजनक है, इसलिए लक्ष्य था कि कम इस्तेमाल होने वाला plastic card wallet में रखने के बजाय iPhone Wallet app में रखा जाए
Wallet pass JSON, images और signature से बना होता है
- Wallet app अभी payment cards, IDs, keys आदि संभालता है, लेकिन 2012 में Passbook launch के समय यह सिर्फ “passes” manage करता था
- Apple के pass documentation के अनुसार pass एक self-contained ZIP file है जिसे email या web के जरिए distribute किया जा सकता है, और इसके अंदर JSON और PNG होते हैं
.pkpassfile की मुख्य संरचना सरल हैpass.json: image नहीं, बल्कि pass की content describe करता हैmanifest.json: दूसरी files के SHA-1 checksums की listsignature:manifest.jsoncontent पर S/MIME signature- supported image files
Codabar support न होना पहली बाधा
- Wallet pass सिर्फ चार तरह के barcodes support करता है
- QR code
- PDF417
- Aztec Code
- Code 128
- Library card Codabar format में था, जो libraries में व्यापक रूप से इस्तेमाल होता है
- संभव है कि library barcode scanners दूसरे linear barcodes भी support करते हों, लेकिन सभी branches में पक्का चलेगा ऐसा format केवल Codabar ही माना जा सकता था
- आखिरकार Wallet के default barcode feature के बजाय, scan करने योग्य Codabar image बनाकर pass में डालनी पड़ी
Pass signing certificate की समस्या
- Wallet pass के लिए cryptographic signature जरूरी है, और उसे Apple certificate authorities में से किसी एक द्वारा trusted key से sign होना चाहिए
- Airline ticket में gate change या seat change जैसे vendor द्वारा pass auto-update करने के use case में signature कुछ हद तक उचित है
- अगर आप Apple developer हैं तो pass signing key अपेक्षाकृत आसानी से मिल सकती है, लेकिन इस काम के लिए सालाना 99 डॉलर देने का इरादा नहीं था
मौजूदा pass generation apps सही क्यों नहीं थे
- पहले से Apple developers द्वारा बनाए गए कई pass design apps मौजूद थे, लेकिन वे जरूरी स्तर का control नहीं देते थे
-
Logo size control
- Apple pass के top-left logo के लिए अधिकतम 50 device-independent pixels height allow करता है
- text के दाईं ओर लगने वाले square logo के लिए करीब 40px height सबसे ठीक थी
- developer को
logo.png,logo@2x.png,logo@3x.pngअलग-अलग देने होते हैं, लेकिन apps आमतौर पर सिर्फ single logo selection allow करते हैं और scale control नहीं देते
-
Screen brightness behavior
- normal supported barcode वाला pass खोलने पर scanner contrast के लिए screen bright हो जाती है
- असल में काम न करने वाला barcode display किए बिना भी iOS से screen bright करवाने के लिए
pass.jsonको सीधे edit करना जरूरी था - मुफ्त में download किए जा सकने वाले apps भी Wallet में save किए जा सकने वाले passes की संख्या सीमित करके payment मांगते थे
Offline generation app में signing key ढूंढना
- कई free-start pass generation apps download किए गए और देखा गया कि offline भी pass generation होता है या नहीं
- airplane mode और Wi-Fi disabled स्थिति में test करने पर, कम से कम एक app offline pass बना सकता था
- key revoke होने से बचाने के लिए उस app का specific नाम नहीं बताया गया
- प्रक्रिया उम्मीद से सरल थी
- Apple silicon Mac पर iOS apps चल सकते हैं, इसलिए app को Mac पर download किया गया
- wrapped iOS app bundle के अंदर एक दिखने वाली
.p12file मिली - PKCS#12 file को import password चाहिए होता है, इसलिए main binary पर
stringsचलाकर password जैसा दिखने वाला string खोजा गया
openssl pkcs12से certificate information check करने पर issuer Apple Worldwide Developer Relations Certification Authority दिखा- certificate chain भी जरूरी होती है; intermediate certificate app bundle के अंदर हो सकता है और X.509 extension field में दिए URL से भी download किया जा सकता है
Pass layout configuration
- Pass style में
boarding pass,coupon,event ticket,generic,store cardमें से एक चुनना होता है - बड़ी horizontal image डालने के लिए
stripimage support करने वाला layout चाहिए था- candidates थे
coupon,event ticket,store card - physical library card से सबसे मिलता-जुलता होने के कारण store card चुना गया
- candidates थे
pass.jsonमें ये values जाती हैंpassTypeIdentifierteamIdentifierformatVersionserialNumberorganizationNamelogoTextdescriptionstoreCardbackgroundColorforegroundColorsharingProhibited
passTypeIdentifierऔरteamIdentifierको Apple certificate subject केUID,OUfields से क्रमशः match करना होता है- एक ही
passTypeIdentifierसे बनाए गए हर pass के लिए uniqueserialNumberचाहिए - Images use case के हिसाब से तैयार की गईं
icon.pngजरूरी है, लेकिन pass में खुद display नहीं होताlogo.pngtop-left में दिखने वाला logo है- 40×40
logo.png, 80×80logo@2x.png, 120×120logo@3x.pnggenerate किए गए logo@3x.pngकोicon.pngके रूप में copy किया गया- पहले से generate किया गया barcode
strip.pngमें डाला गया
Codabar barcode image बनाना
- iOS
strip.pngको device screen के box के हिसाब से scale और crop करता है, इसलिएstrip.pngको अलग-अलग resolution में 3 variants बनाने की जरूरत नहीं थी - दोनों library cards start और end symbols के रूप में A और D इस्तेमाल करते हैं
- start/end symbols barcode scanner होने पर सबसे आसानी से verify किए जा सकते हैं, और scanner न हो तो Wikipedia की Codabar encoding table से आंखों से compare किए जा सकते हैं
- online तुरंत इस्तेमाल करने लायक Codabar generators ज्यादा नहीं थे, लेकिन format खुद implement करना आसान था
- prototype में Rust के लिए Barcoders library से SVG बनाया गया, SVG adjust किया गया, फिर PNG में export किया गया
- final layout scanability और iOS में shrink display को ध्यान में रखकर तय किया गया
- barcode height को start/end symbols सहित कुल symbols की संख्या के 2 गुना units पर set किया गया
- उदाहरण के लिए 13-digit barcode number में 15 symbols होते हैं, इसलिए height 30 units बनाई गई
- start से पहले और end के बाद 15 units quiet space रखा गया
- barcode के ऊपर-नीचे 50 units padding रखा गया
- हर unit को 8 pixels तक expand किया गया ताकि iOS हमेशा image को shrink करे
- उदाहरण वाले 15-symbol barcode में final image height 1040 pixels है और barcode की अपनी height 240 pixels है
- ऊपर वाले layout का Codabar BMP बनाने और
sipsसे PNG में convert करने के लिए 69-line shell script लिखी गई - script output को
strip.pngके रूप में save करने पर pass में डालने के लिए barcode image तैयार हो जाती है
Barcode number display और screen brightness workaround
- Barcode number को
secondaryFieldsके रूप में barcode के नीचे display किया गयाkey:numberlabel:CARD NUMBERvalue: card number
- iOS barcode वाला pass select करने पर scanner की मदद के लिए screen bright कर देता है
- सिर्फ image के रूप में डाले गए Codabar से iOS यह नहीं मानता कि barcode मौजूद है
pass.jsonके top level पर खाली barcode item specify करके इस behavior का workaround किया गयाmessageखाली string हैformatPKBarcodeFormatCode128हैmessageEncodingiso-8859-1है
- इस तरीके से pass के bottom में barcode दिखाए बिना भी iPhone ने screen को ऐसे bright किया जैसे pass में barcode हो
Signing और packaging
- सभी files तैयार होने के बाद
manifest.jsongenerate करना होता है manifest.jsonएक object है जिसमें filename key और SHA-1 checksum value होता हैsha1sum,jqको combine करके PNG files औरpass.jsonका manifest generate किया गया- manifest signing
openssl smimecommand से की गई- signer certificate
- private key
- Apple WWDR intermediate certificate
- input
manifest.json - output
signature
openssl smimeके-attimeoption से desired signing time specify किया जा सकता है- option value UNIX epoch होती है
- Apple से मिला या खोजा गया certificate expire हो चुका हो, तब भी उस समय के हिसाब से sign किया जा सकता है
- अंत में इन files को ZIP करके
.pkpassबनाया गया- PNG images
pass.jsonmanifest.jsonsignature
Test results और खटकने वाली बातें
- macOS में pass preview tool है, जिससे check किया जा सकता है कि pass valid है और आम तौर पर सही दिख रहा है
- invalid होने पर
Console.appमें errors मिल सकते हैं - preview tool 100% accurate नहीं है, लेकिन इसमें iCloud के जरिए iPhone पर भेजने वाला button है
- तैयार pass अभी असली library में test नहीं किया गया था
- अलग barcode scanner phone screen पर barcode को असली plastic card की तरह पढ़ सका
- हालांकि screen brightness maximum करने पर यह अच्छी तरह read हुआ
- खाली barcode workaround से बढ़ी brightness से भी ज्यादा bright set किया गया था
- अच्छा है कि pass specification 10 साल में लगभग नहीं बदला, लेकिन PNG और JSON वाले harmless pass को sign करने के लिए सालाना 99 डॉलर Apple Developer membership चाहिए होना खटकता है
- कुछ pass features के लिए signature जरूरी मानी जा सकती है, लेकिन इस काम में जो किया गया उसके लिए signature जरूरी नहीं होनी चाहिए
- अगर Apple Wallet में Codabar support जोड़ दे, तो library system के सभी scanners Code 128 support करते हैं या नहीं इसका audit किए बिना भी digital library cards support किए जा सकते हैं
1 टिप्पणियां
Hacker News की राय
अगली बार ORCA कार्ड भी कवर करें तो अच्छा होगा। Seattle अमेरिका के तकनीकी केंद्रों में से एक है, लेकिन subway/public transit खुद भी खास नहीं है, और तकनीकी रूप से भी मेरे इस्तेमाल किए हुए लगभग सभी बड़े शहरों के public transit से पीछे है
यूरोप के किसी भी शहर, CDMX, Denver से तुलना करें तो वे Seattle से काफी आगे हैं, और निजी तौर पर मुझे लगता है Denver सबसे अच्छा था
ORCA चलाने वाली एजेंसियों में से एक ने कभी Android ऐप में NFC सपोर्ट जोड़ने पर ब्लॉग पोस्ट डाली थी, लेकिन वह पोस्ट अब गायब है और कई साल बाद भी वह फीचर नहीं है
अगर वही कार्ड इस्तेमाल करें तो transfer, कुछ दिनों वाले pass जैसी चीजें भी seamless तरीके से संभल जाती हैं, और किसी तय अवधि में एक निश्चित संख्या से ज्यादा rides लेने पर आगे charge नहीं करते—इस तरह सही fare अपने-आप लागू हो जाता है
हमारे office का door NFC card से खुलता है, इसलिए मैंने देखा था कि iOS पर यह संभव है या नहीं; याद है कि Apple सामान्य PassKit की तुलना में NFC hardware को ज्यादा सख्ती से control करता है, इसलिए सामान्य apps से मुश्किल लगता है
ORCA ने कहा था कि 2023 के अंदर tap payment आएगा, तो सच होने के लिए अब करीब दो महीने बचे हैं
Google ने पोस्ट किया है कि Google Wallet में ORCA जल्द support होगा, इसलिए मैं optimistic हूं
अगर Android users को यह बात पसंद नहीं कि Google Wallet, Apple Passbook की तरह कोई भी barcode जोड़ने नहीं देता, तो F-Droid पर Loyalty Card Keychain नाम का बेहतरीन app है: https://f-droid.org/en/packages/protect.card_locker/
आप number manually डाल सकते हैं या मौजूदा barcode scan कर सकते हैं, और Codabar समेत कई barcode formats में से एक चुनकर save कर सकते हैं। app की main screen पर item tap करने पर generated barcode दिखता है और screen brightness भी बढ़ जाती है
शायद इसलिए कि barcode दिखाने के अलावा यह ज्यादा कुछ नहीं करता, app बहुत जल्दी खुलता है। इसका सिर्फ एक काम है, लेकिन शायद यह मेरा सबसे पसंदीदा app है
आजकल लगता है Catima इस्तेमाल करने को कहा जाता है; मैंने थोड़ी देर इस्तेमाल किया तो वह भी उतना ही simple लगा और उसी codebase पर आधारित दिखा
असुविधाजनक है, लेकिन काम हो जाता है, और privacy policy भी अच्छी है
मुझे समझ नहीं आता कि pass को cryptographically signed होना और Apple certificate authority को ज्ञात key से signed होना क्यों जरूरी समझा जाए। ऐसी updates के लिए पहले से अच्छी तरह supported HTTPS है
शायद Apple चाहता हो कि pass केवल update के समय ही नहीं, बल्कि phone पर offline भी verify हो सके, लेकिन फिर भी यह अजीब है। malicious actor pass को update करने के बजाय सीधे replace कर सकता है
इसे Apple developer account से जोड़ने से update वाली समस्या में कैसे मदद मिलती है, यह मुझे बिल्कुल नहीं समझ आता
Apple-approved entity होने की requirement का जो कारण दिमाग में आता है, वह fake tickets बेचना है। “Concert X ticket” नाम की pkpass file असली है या नहीं, यह उस requirement के साथ भी जानने का कोई तरीका नहीं है
fraud report आने पर उस developer account को cancel करके response देने की कोशिश हो सकती है, लेकिन यह भी solution जैसा नहीं लगता। developer account की cost पकड़े जाने से पहले fraud से कमाए जा सकने वाले पैसे से कहीं कम होने की संभावना है
मैं तो library card number वाला barcode PNG खुद को email कर देता हूं, और kiosk के सामने Photos या Gmail app में खोलकर इस्तेमाल करता हूं
मैंने MakePass app से StarBucks membership code वाला pass बनाया, और जब मैं अक्सर जाने वाले store के पास पहुंचता हूं तो phone lock screen पर StarBucks pass अपने-आप suggest करता है
event tickets के लिए भी इसी तरह location और time range सेट कर दें तो venue पर पहुंचने पर pass ढूंढने की जरूरत नहीं पड़ती, वह अपने-आप suggest हो जाता है। event खत्म होने के बाद वह suggest नहीं करता और “Expired Passes” section में चला जाता है, जिससे main screen clutter नहीं होती
MakePass: https://pvieito.com
अच्छा blog post था, लेकिन अंत में “अभी इस pass को असली library में test नहीं किया है” लिखा था
समझता हूं कि यह मजे के लिए किया गया project था, लेकिन result share करने से पहले final solution test करने में लगने वाले 10 minutes क्यों नहीं लगाए, यह समझ नहीं आया
बारकोड बनाते समय मैं व्यक्तिगत रूप से PostScript में बने बारकोड जनरेटर को पसंद करता हूँ
https://bwipp.terryburton.co.uk/
इस समस्या को लाइब्रेरी कार्ड की फोटो खींचकर हल कर लिया। किताब उधार लेते समय फोटो खोलकर स्कैनर के सामने रख देना होता है
फोन के फोटो एल्बम में अपने सभी ID कार्ड सेव रखता हूँ
Android पर ऐसा ही कुछ करना हो, तो Google Play और F-Droid पर Catima उपलब्ध है। यह कई तरह के बारकोड सपोर्ट करता है
https://catima.app/
सस्ते laser-based 1D barcode scanners स्क्रीन से बारकोड नहीं पढ़ पाते। eInk शायद काम कर जाए
जिस supermarket में मैं अक्सर जाता हूँ, उसका membership card बारकोड-आधारित है, इसलिए असुविधा होती है; लेकिन अच्छी बात है कि barcode reader keyboard की नकल करता है, इसलिए code को सीधे keyboard से टाइप किया जा सकता है
camera-based scanners को फर्क नहीं पड़ता कि barcode की lighting ambient light से है, अपनी LED से है या backlit screen से; लेकिन laser-based systems अपनी ही रोशनी के reflection पर निर्भर करते हैं, इसलिए active backlit screen पर बिल्कुल काम नहीं करते
सोचता हूँ कि e-ink या passive LCD display पर ये काम करते हैं या नहीं
देखने में यह एक साधारण red-line 2D type जैसा लगता है, लेकिन लगता है hardware भी सच में मायने रखता है
KCLS account number तो बस याद कर लिया। याद करने में करीब 30 सेकंड ही लगने चाहिए; व्यक्ति पर निर्भर है, लेकिन मुझे लगता है यह तरीका ज्यादा तेज होगा
इसके बाद barcode scan करने के बजाय account number डालना होता है, और संभव है कि इसमें फोन निकालकर तैयार करने से कम समय लगे
SPL में भी यही तरीका है या नहीं, पता नहीं। Seattle में नहीं रहता, इसलिए जाँच नहीं कर सकता