Keselamatan
Bagaimana peti besi itu dibina, dan apakah pencerobohan yang akan ditemui.
Kemas kini terakhir 21 September 2026 · AssuredAuth, oleh CircleRoll LLC
Ini adalah penerangan umum tentang bagaimana AssuredAuth melindungi rahsia dua faktor, kata laluan dan kad yang anda simpan di dalamnya. Ia ditulis supaya pembaca yang mementingkan keselamatan boleh menyemak setiap dakwaan terhadap aplikasi dan terhadap vektor ujian yang diterbitkan (tersedia kepada mana-mana pengulas atas permintaan di hello@assuredauth.com). Ia menyatakan apa yang benar dan tidak lebih daripada itu: tiada apa yang didakwa di sini sebagai tidak dapat diserang, dan tiada apa yang dijanjikan dalam peratusan.
Versi ringkas: peti besi wujud di satu tempat, iaitu telefon anda. Setiap nilai di dalamnya disulitkan dengan kunci yang disimpan oleh perkakasan keselamatan telefon dan tidak boleh dieksport. Kami tidak menjalankan pelayan peti besi, tidak menyimpan salinan dan tidak menyimpan kunci. Fail sandaran hanya akan meninggalkan telefon selepas ia disulitkan di bawah frasa laluan yang tidak pernah disimpan di mana-mana sahaja.
Laporkan masalah: hello@assuredauth.com. Lihat "Melaporkan kelemahan" pada bahagian akhir.
1. Apa yang disulitkan, dengan apa
| Data | Di telefon | Kunci |
|---|---|---|
| Rahsia dua faktor (TOTP/HOTP/Biji benih wap) | Di telefonKedai yang disokong oleh Keystore (iOS) / Android | KunciKunci terikat perkakasan platform; baris pangkalan data hanya menyimpan rujukan (secretRef), tidak pernah menyimpan benih |
| Kata Laluan (nilai kata laluan, nota) | Di telefonBaris tertutup: AES-256-GCM, nonce 96-bit rawak setiap nilai | KunciKunci data rawak 256-bit, yang dibungkus oleh kunci perkakasan dalam §2 |
| Kad (nombor, tarikh luput, nama pada kad, CVC) | Di telefonMeterai yang sama seperti kata laluan; CVC adalah pilihan dan hanya disimpan jika anda memasukkannya | KunciKunci data yang sama |
| Metadata (nama perkhidmatan, nama pengguna, ikon, susunan isihan) | Di telefonPangkalan data aplikasi (SwiftData / Bilik) | KunciDilindungi oleh penyulitan fail sistem pengendalian; dianggap sebagai bukan rahsia |
| Fail sandaran (.authbackup) | Di telefonDi mana sahaja anda meletakkannya: Fail, iCloud Drive, Google Drive appDataFolder, helaian kongsi | KunciKunci yang diperoleh daripada frasa laluan anda (§3). Apple dan Google menerima fail yang dimeteraikan dan tiada yang lain |
| Aplikasi teman Watch / Wear | Di telefonRantai Kunci jam tangan itu sendiri / Keutamaan Dikongsi Tersulit | KunciKekunci platform jam tangan; dipindahkan melalui saluran peranti berpasangan platform |
| Trafik sambungan desktop (kod sekali guna atas permintaan) | Di telefonTidak disimpan; disampaikan sebagai sampul surat yang disulitkan dari hujung ke hujung | KunciPasangan kunci X25519 setiap pasangan, kunci persendirian dalam Rantai Kunci / Stor Kunci; geganti hanya melihat teks sifer |
Diagnostik tidak mempunyai kaedah yang menerima rahsia. Tiada peristiwa analitik yang membawa medan bilik kebal. Tiada nilai daripada bilik kebal yang pernah ditulis ke log, dalam mana-mana binaan.
2. Tempat kekunci berada, pada setiap platform
iOS. Kekunci data dibalut oleh kunci yang dijana di dalam Secure Enclave (kSecAttrTokenIDSecureEnclave) dengan kawalan akses .privateKeyUsage + .userPresence, accessibility …ThisDeviceOnly, dalam kumpulan akses Keychain yang dikongsi aplikasi supaya sambungan AutoFill boleh menggunakan kunci yang sama. Kekunci peribadi tidak boleh dibaca keluar dari Enclave oleh aplikasi, oleh sandaran atau oleh penyahpepijat; Enclave hanya bersetuju untuk menggunakannya selepas pengguna hadir (Face ID, Touch ID atau kod laluan peranti). ThisDeviceOnly bermaksud sandaran iCloud atau iTunes telefon tidak membawa kunci tersebut; telefon yang dipulihkan bermula dengan peti besi kosong dan meminta fail sandaran dan frasa laluan anda. Telefon tanpa kod laluan tidak boleh mengakses kunci .userPresence (Enclave enggan membuatnya), dan simulator mengambil laluan yang sama mengikut reka bentuk (gesaan kehadirannya ialah amaran yang tidak dapat dijawab oleh ujian): di sana kunci data ialah item Rantai Kunci peranti sahaja yang biasa — masih keluar daripada setiap sandaran, masih tidak boleh dibaca semasa telefon dikunci, tetapi tanpa gesaan kedua — dan skrin Keselamatan menyatakan dengan tepat perkara itu dan mencadangkan penetapan kod laluan.
Android. Kekunci data dibalut oleh kunci AndroidKeyStore AES-256, yang dijana dalam StrongBox apabila peranti mempunyai satu (selain TEE), dengan setUserAuthenticationRequired(true) dan kesahan pengesahan 30 saat selepas kelayakan biometrik atau peranti, setUnlockedDeviceRequired(true) dan setInvalidatedByBiometricEnrollment(true) dibiarkan hidup. Bendera terakhir itu jujur dan bukannya menanggung beban: Android hanya menggunakannya pada kunci yang memerlukan biometrik pada setiap penggunaan, jadi pada kunci 30 saat ini dengan kelayakan peranti dibenarkan, ia tidak mengubah apa-apa — apa yang menghalang jari orang yang tidak dikenali daripada mengaksesnya ialah pendaftaran seseorang memerlukan PIN, dan mengalih keluar kunci skrin akan membatalkan kunci tersebut buat selama-lamanya. Kekunci stor kunci tidak boleh dieksport dan dikecualikan daripada sandaran awan Android. Domain yang dinamakan oleh apl pada paparannya sendiri (webDomain) hanya dipercayai daripada pelayar yang diketahui; daripada mana-mana pakej lain, ia juga mestilah salah satu yang telah disahkan oleh sistem untuk pakej tersebut (Pautan Aset Digital), kerana mana-mana apl boleh menuntut mana-mana domain.
Apakah maksud ini untuk fail pangkalan data yang dicuri. Fail SQLite dan baris yang dimeteraikan adalah teks sifer. Kunci yang membukanya berada dalam perkakasan keselamatan pada telefon tempat fail itu berasal dan tidak boleh disalin dengan fail tersebut. Tiada apa-apa untuk diteka di luar talian: kunci data adalah rawak, bukan diperoleh daripada apa-apa yang dipilih oleh seseorang.
3. Fail sandaran
Sandaran adalah satu perkara yang meninggalkan telefon, jadi ia adalah satu-satunya tempat serangan luar talian boleh dilakukan secara prinsip. Reka bentuknya menjadikan serangan itu mahal dan memberikannya sesedikit mungkin untuk digunakan:
- Frasa laluan sekurang-kurangnya 12 aksara (helaian menolak lebih sedikit dan menunjukkan bar kekuatan).
- Tiada petunjuk frasa laluan disimpan di mana-mana sahaja, dalam fail atau dalam aplikasi.
- Garam 16-bait rawak baharu dan nonce 12-bait untuk setiap fail yang ditulis.
- Seluruh badan fail adalah AES-256-GCM, jadi frasa laluan yang salah atau fail yang rosak akan ditolak, dan tidak akan dinyahsulit menjadi sampah.
- Pengepala (format, versi, parameter KDF, garam) terikat ke dalam tag GCM sebagai data pengesahan tambahan, jadi fail yang faktor kerjanya telah diedit tidak akan dibuka.
Fail ini JSON dan boleh dibaca dalam mana-mana editor teks; hanya teks sifer sahaja yang legap. Seseorang yang menemui fail itu dalam tempoh lima tahun, dengan aplikasinya yang telah tiada, boleh melihat dengan tepat bagaimana ia dimeteraikan dan membukanya dengan OpenSSL atau mana-mana pustaka Argon2.
Format v1 (dihantar dalam 1.0, kekal boleh dibaca)
{
"format": "authbackup",
"version": 1,
"kdf": "PBKDF2-HMAC-SHA256",
"rounds": 600000,
"salt": "<base64, 16 bytes>",
"cipher": "AES-256-GCM",
"nonce": "<base64, 12 bytes>",
"ciphertext": "<base64>",
"tag": "<base64, 16 bytes>"
}
| Langkah | Bait |
|---|---|
key | PBKDF2-HMAC-SHA256(passphrase as UTF-8, salt, 600000 rounds, 32 bytes) |
aad | UTF-8("authbackup:1:600000:") ‖ salt (bait garam mentah, bukan base64) |
ciphertext, tag | AES-256-GCM(key, nonce, plaintext, aad); tag 16 bait, disimpan secara berasingan |
plaintext | UTF-8 JSON, kekunci disusun: {"accounts":[…],"exportedAt":"…Z","passwords":[…],"version":1} |
Nota keserasian: Android 1.0 menulis varian v1 — kdf dalam huruf kecil, tiada kekunci tag (tag 16-bait dilampirkan pada teks sifer), tiada data tambahan. Kedua-dua platform terus membaca fail tersebut (apabila tag tiada: bahagikan 16 bait terakhir, buka dengan AAD kosong; bandingkan kdf secara tidak sensitif huruf besar-kecil) dan kedua-duanya kini hanya menulis susun atur di atas.
Format v2 (semasa; lalai untuk sandaran baharu)
{
"format": "authbackup",
"version": 2,
"kdf": "Argon2id",
"memoryKiB": 65536,
"passes": 3,
"lanes": 1,
"salt": "<base64, 16 bytes>",
"cipher": "AES-256-GCM",
"nonce": "<base64, 12 bytes>",
"ciphertext": "<base64>",
"tag": "<base64, 16 bytes>"
}
| Langkah | Bait |
|---|---|
key | Argon2id(version 0x13, passphrase as UTF-8, salt, m = 65536 KiB, t = 3, p = 1, tagLength 32, no secret, no associated data) |
aad | UTF-8("authbackup:2:argon2id:65536:3:1:") ‖ salt |
ciphertext, tag | AES-256-GCM(key, nonce, plaintext, aad); tag 16 bait, disimpan secara berasingan |
plaintext | UTF-8 JSON, kekunci disusun: {"accounts":[…],"cards":[…],"exportedAt":"…Z","passwords":[…],"version":2} |
Argon2id ialah pelaksanaan rujukan C (phc-winner-argon2, CC0), yang dijual pada kedua-dua platform. 64 MiB dan 3 hantaran mengambil masa kira-kira satu saat pada telefon semasa dan menjadikan setiap tekaan menyebabkan memori dan masa pada sebarang perkakasan — sifat PBKDF2 kekurangan berbanding pelantar GPU, dan sebab v2 wujud. Pembaca mengabaikan kekunci yang tidak diketahuinya, jadi pembaca v1 yang diberikan badan v2 tidak pernah melihat kad.
Bukti
Tiga fail vektor ujian (sandaran v1, sandaran v2 dan Argon2id) dijana oleh pelaksanaan ketiga, bebas daripada kedua-dua aplikasi (OpenSSL Node untuk PBKDF2 dan AES-GCM, WebAssembly Argon2id yang disemak pada masa penjanaan terhadap jawapan yang diterbitkan oleh pelaksanaan rujukan). Setiap satu menyimpan frasa laluan, garam, nonce, teks biasa, kunci terbitan, AAD, teks sifer dan tag yang dijangkakan, dan fail lengkap. Ujian unit pada iOS dan pada Android membaca fail yang sama dan menegaskan bait yang sama — jadi sandaran yang dimeteraikan pada satu platform terbukti, bukan diandaikan, terbuka pada platform yang lain, dan persetujuan ketiga-tiganya bukanlah dua salinan kesilapan yang sama. Alat pendamping membuka fail yang sebenarnya ditulis oleh telefon dengan pelaksanaan ketiga yang sama dan menyemak pengepala terhadap peraturan di atas (betul-betul kekunci format, jadi tiada petunjuk atau nama boleh hadir; garam 16-bait, nonce 12-bait, tag 16-bait disimpan secara berasingan; versi 2 pada tepat 64 MiB / 3 / 1; frasa laluan yang salah ditolak); larian iOS automatik menulis satu pada simulator dan membukanya dengan cara itu, dan mencari bekas aplikasi simulator, bekas Kumpulan Aplikasi dan pangkalan data rantai kunci untuk setiap kata laluan dan nombor kad yang diutamakan sebagai UTF-8 dan UTF-16 (0 hits).
4. Model ancaman
| Situasi | Apa yang mereka ada | Apa yang mereka dapat |
|---|---|---|
| Telefon hilang atau dicuri, terkunci | Apa yang mereka adaPeranti, fail pangkalan data, baris yang dimeteraikan | Apa yang mereka dapatTeks Sifer. Kunci pembalut berada dalam Enklaf Selamat / Kotak Kuat dan hanya dilepaskan selepas peranti dikunci serta biometrik atau kod laluan baharu. Mengelap telefon dari jauh (Cari Peranti Saya / Cari Peranti Saya) akan memusnahkan bahan kunci bersamanya. |
| Fail sandaran yang dicuri | Apa yang mereka adaFail .authbackup daripada akaun awan, e-mel, komputer riba | Apa yang mereka dapatBadan AES-256-GCM di bawah kunci yang diperoleh daripada frasa laluan sekurang-kurangnya 12 aksara, dengan garam setiap fail dan Argon2id pada 64 MiB × 3 hantaran (v2) atau PBKDF2 pada 600,000 pusingan (v1). Tiada petunjuk, tiada nama pengguna, tiada senarai akaun yang jelas. Setiap tekaan memerlukan terbitan penuh; tiada jalan pintas. Frasa laluan yang kukuh adalah keseluruhan pertahanan di sini, dan aplikasi menyatakannya pada helaian. |
| Peranti yang dicuri dengan skrin tidak berkunci | Apa yang mereka adaTelefon di tangan anda, tidak berkunci | Apa yang mereka dapatSenarai Kod. Bilik kebal (kata laluan, kad) berada di belakang kunci aplikasi dan mengunci semula pada pemasa kunci automatik (serta-merta / 1 minit / 5 minit); nilai yang dinyahsulit hanya wujud dalam memori semasa skrinnya memaparkannya. Isi automatik dan eksport teks biasa meminta biometrik baharu walaupun aplikasi dibuka. Hidupkan kunci aplikasi dengan "Segera" jika ini yang anda bimbangkan. |
| Aplikasi berniat jahat pada telefon yang sama | Apa yang mereka adaKotak pasir, papan klip, kebolehcapaian atau helah tindanan aplikasi lain | Apa yang mereka dapatIa tidak boleh membaca fail kami (sandboxing platform) atau menggunakan kunci kami (kunci terikat pada identiti tandatangan kami dan kehadiran pengguna). Salinan akan dipadamkan daripada papan keratan selepas 30 saat; pada Android, salinan akan ditandai sensitif dan dikecualikan daripada sejarah papan keratan. Skrin peti besi ditetapkan FLAG_SECURE pada Android (tiada tangkapan skrin, tiada rakaman skrin, kosong dalam penukar); iOS mengosongkan lakaran kecil penukar. Isi automatik pada Android hanya dihidangkan kepada aplikasi yang telah disahkan oleh sistem terhadap domain yang disimpan (Pautan Aset Digital), jadi aplikasi yang serupa tidak ditawarkan kata laluan anda. |
| Halaman pancingan data | Apa yang mereka adaTapak yang kelihatan seperti yang anda simpan | Apa yang mereka dapatTiada apa yang terisi. Pemadanan adalah mengikut domain yang boleh didaftarkan (senarai akhiran awam, dibundel dan dikemas kini dengan aplikasi): login.example.com dan example.com sepadan, example.com.evil.net dan examp1e.com tidak. Pelayar dalam aplikasi sepadan dengan cara yang sama dan hanya mengisi ke dalam bingkai yang diminta, disemak semula terhadap asal bingkai itu sendiri pada saat pengisian; hos tanpa domain yang boleh didaftarkan sendiri — alamat IP, nama kosong pada rangkaian setempat — sepadan dengan tepat dan tiada yang lebih longgar. AutoFill iOS menambah semakan domain berkaitan Apple. Kata laluan yang mesti anda tampal dengan tangan ke dalam yang serupa masih merupakan risiko; aplikasi tidak boleh mengalih keluarnya, hanya mengelakkan daripada membantu. |
| Pelayan kami sendiri | Apa yang mereka ada— | Apa yang mereka dapatTiada pelayan peti besi. AssuredAuth tidak mempunyai akaun, tiada daftar masuk dan tiada salinan peti besi anda, jadi tiada apa-apa milik anda di pihak kami yang boleh dicuri dan dibocorkan. Dua perkara dijalankan di sisi pelayan, yang kedua-duanya tidak menyentuh peti besi: peti mel geganti untuk sambungan desktop, yang menyimpan sampul surat yang disulitkan dari hujung ke hujung (kod sekali guna, dipadamkan apabila dibaca; geganti tidak pernah mempunyai kunci), dan pelayan keluar sambungan peribadi pilihan, yang membawa trafik dan tidak menyimpan log akses. |
| Sepina atau permintaan kerajaan | Apa yang mereka adaProses undang-undang yang ditujukan kepada kami | Apa yang mereka dapatTiada apa-apa untuk diserahkan: kita tidak memegang peti besi, tiada kunci, tiada frasa laluan dan tiada sandaran. Kita boleh dipaksa untuk mengatakannya; kita tidak boleh dipaksa untuk menghasilkan apa yang tidak wujud. |
5. Papan klip, tangkapan skrin dan memori
- Salinan meletakkan nilai pada papan klip selama 30 saat, kemudian memadamkannya jika ia masih milik kita. Pada Android, klip ditanda EXTRA_IS_SENSITIVE jadi sistem menyembunyikannya daripada pratonton dan sejarah papan klip; pada iOS, item papan tampal adalah setempat sahaja (tidak Diserahkan kepada peranti lain).
- Skrin peti besi (Kata Laluan, Kata Laluan, Kad, Kad, helaian frasa laluan, eksport teks biasa) ditetapkan FLAG_SECURE pada Android. iOS tidak mempunyai bendera yang setara; aplikasi mengosongkan lakaran kecilnya dalam penukar aplikasi dan nilai berada di belakang togol mata secara lalai.
- Nilai yang dinyahsulit hanya berada dalam memori semasa skrin memaparkannya dan digugurkan apabila ia hilang atau aplikasi dikunci. Kekunci data dibuka untuk permintaan dan tidak disimpan dalam cache merentasi kunci.
- Eksport teks biasa wujud (jadi anda sentiasa boleh keluar) dan berada di sebalik helaian pengesahan dan biometrik baharu, dan skrinnya juga FLAG_SECURE.
6. Isi Auto: apa yang mengisi, dan apa yang tidak
| Di mana | Kata Laluan | Kad |
|---|---|---|
| iOS: Safari dan aplikasi (sambungan AutoFill) | Kata LaluanYa, selepas Face ID / Touch ID / kod laluan baharu dalam sambungan (LAContext), dan hanya untuk domain yang boleh didaftarkan yang entri tersebut disimpan, dengan semakan domain berkaitan Apple untuk aplikasi | KadTidak. Isi automatik kad dalam Safari adalah milik Apple sahaja; skrin kad tertera "Mengisi dalam pelayar AssuredAuth dan dengan Salinan" dan tidak menjanjikan apa-apa lagi. |
| Android: aplikasi dan Chrome (AutofillService) | Kata LaluanYa, pengesahan setiap set data: sistem menunjukkan BiometricPrompt sebelum pengisian; pakej aplikasi hanya dipadankan apabila Pautan Aset Digital mengikatnya pada domain yang disimpan | KadYa, petunjuk creditCardNumber, creditCardExpiration* dan creditCardSecurityCode, get biometrik yang sama |
| Pelayar AssuredAuth (kedua-dua platform) | Kata LaluanYa, melalui domain yang boleh didaftarkan — hos yang tiada padanannya sendiri — ke dalam bingkai yang diminta, biometrik sebelum pengisian | KadYa, melalui pengesanan medan, biometrik sebelum pengisian |
| Butang salin | Kata LaluanDi sebalik kunci aplikasi, papan keratan 30 saat | KadNombor, tamat tempoh, CVC (peraturan yang sama) |
Tiada apa yang akan memenuhi hos yang serupa. Tiada apa yang akan memenuhi tanpa biometrik.
7. Apa yang tidak pernah berlaku
Tiada pelayan vault. Tiada analitik yang membawa medan vault. Tiada eksport teks biasa tanpa helaian pengesahan dan biometrik baharu. Tiada SDK pihak ketiga dimuatkan pada skrin vault. Tiada tangkapan skrin vault. Tiada petunjuk frasa laluan. Tiada pengelogan nilai, dalam mana-mana binaan.
8. Apa yang kita tidak dapat lindungi daripadanya
Frasa laluan yang cukup lemah untuk diteka. Telefon yang sistem pengendaliannya telah dicerobohi pada peringkat akar (peranti yang telah di-jailbreak atau di-root boleh berbohong kepada aplikasi tentang semua perkara di atas). Seseorang yang diperhatikan semasa menaip. Perisian hasad pada desktop yang anda tampal. Kami mengatakan ini supaya senarai di atas dibaca sebagaimana adanya: perkara yang boleh dialih keluar oleh reka bentuk, dialih keluar.
9. Semak status
Reka bentuk ini telah diuji unit terhadap jawapan yang diketahui yang diterbitkan pada kedua-dua platform dan terhadap vektor merentas platformnya sendiri. Semakan luaran berada dalam senarai pemilik sebelum peti besi diiklankan pada penyenaraian gedung; sehingga ia berlaku, dokumen ini akan menyatakannya di sini.
10. Di mana sesuatu berjalan
Tiada apa-apa bahagian peti besi yang keluar dari telefon, tetapi beberapa perkara di sekelilingnya berjalan pada mesin orang lain. Ini adalah senarainya, dan apa yang disimpan oleh setiap satunya; aliran data itu sendiri diterangkan dalam dasar privasi di https://assuredauth.com/privacy.
- Google Cloud / Firebase — peti mel geganti untuk sambungan desktop (sampul surat yang disulitkan hujung ke hujung, dipadamkan apabila dibaca), token push, keadaan pembelian dan mesej yang dihantar melalui borang hubungan.
- Vercel — assuretauth.com, halaman-halamannya dan fungsi-fungsi kecil di sebaliknya.
- Vultr — pelayan keluar sambungan peribadi. Trafik melaluinya; tiada apa yang disimpan.
- Apple dan Google Play — pembelian dan langganan, di kedai mereka sendiri.
- PostHog — analitik produk: kiraan apa yang digunakan, tidak terikat dengan identiti.
- RevenueCat — keadaan langganan: aktif atau tamat tempoh, dan pada pelan yang mana.
Setiap satu menyimpan apa yang tertera dalam barisnya dan tiada apa-apa daripada peti besi. Senarai itu berubah apabila produk itu berubah, dan bahagian ini juga berubah bersamanya.
Melaporkan kelemahan
Jika anda percaya anda telah menemui kelemahan dalam apa-apa yang diterangkan di sini, tulis kepada hello@assuredauth.com dengan subjek "Keselamatan". Sila sertakan platform, versi aplikasi dan langkah-langkahnya; bukti yang menggunakan data anda sendiri sudah memadai, dan kami meminta anda untuk tidak mengujinya dengan bukti orang lain. Kami tidak menawarkan kunci PGP; jika laporan tidak boleh dihantar melalui e-mel biasa, nyatakan dalam mesej pertama dan kami akan mengatur cara lain.
Apa yang kami janjikan sebagai balasan: kami akan mengakui dalam tempoh tiga hari bekerja, memastikan anda sentiasa dimaklumkan semasa kami berusaha, membetulkan apa yang sebenar sebelum apa-apa mengenainya diterbitkan, dan memberi kredit kepada anda di sini jika anda ingin diberi kredit. Kami tidak akan mengambil tindakan undang-undang ke atas penyelidikan yang dilakukan dengan niat baik dalam skop di bawah.
Dalam skop: aplikasi iOS dan Android, aplikasi jam tangan, sambungan desktop, assuretauth.com dan APInya. Di luar skop: App Store dan Google Play sendiri, penyedia yang disenaraikan di atas, kejuruteraan sosial sesiapa sahaja dan penafian perkhidmatan.
Tiada ganjaran buat masa ini. Laporan akan dibalas dengan pembetulan dan ucapan terima kasih, bukan dengan wang.