1 poin oleh GN⁺ 4 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Token keamanan menandatangani di dalam perangkat tanpa mengekspor kunci privat ke luar perangkat, dan memerlukan tindakan fisik dari pengguna sehingga penyerang jarak jauh sulit membuat tanda tangan sewenang-wenang
  • Dapat digunakan untuk autentikasi SSH, U2F, login lokal tanpa kata sandi, sudo, dan penandatanganan commit git; perangkat keamanan bawaan pada laptop dan ponsel modern dapat menggantikan YubiKey
  • File “kunci privat” yang dibuat dengan ssh-keygen -t ed25519-sk bukanlah kunci privat yang sebenarnya, melainkan handle yang menunjuk ke kunci di dalam token, dan file kunci SSH yang sama dapat dibuat di komputer lain dengan token yang sama
  • Di MacBook, secure element dapat disetel sebagai kunci SSH sehingga login SSH berbasis Touch ID dimungkinkan, dan untuk penandatanganan commit git diperlukan pengaturan user.signingKey dengan ssh-agent dan format key::, bukan jalur file
  • Token keamanan tidak memungkinkan pemulihan kunci privat saat hilang dan memiliki risiko kegunaan karena pengguna bisa terbiasa menyentuhnya berulang kali; pada laptop Windows, Windows Hello dapat mengonfirmasi penggunaan kunci SSH dengan pengenalan wajah, sidik jari, atau PIN

Kelebihan dan batasan token keamanan

  • Struktur inti yang mencegah serangan jarak jauh

    • Token keamanan adalah perangkat yang menyimpan pasangan kunci privat/publik di dalam perangkat; kunci publik bisa dikeluarkan dengan mudah, tetapi kunci privat tidak keluar dari perangkat
    • Saat paket data yang akan ditandatangani dikirim ke perangkat, penandatanganan dilakukan di dalam perangkat dengan kunci privat, dan biasanya memerlukan tindakan fisik pengguna seperti menekan tombol sentuh yang berkedip
    • Bahkan jika penyerang jarak jauh mendapat akses ke komputer, token keamanan tidak akan membuat tanda tangan sewenang-wenang tanpa tindakan pengguna di dunia nyata, sehingga tampak lebih baik dibanding pendekatan menyimpan seluruh pasangan kunci privat/publik SSH sebagai file di direktori ~/.ssh
    • Ada juga opsi bagi yang menginginkan firmware FOSS seperti SoloKeys dan Nitrokeys
    • Token keamanan kelas lebih tinggi menambahkan fitur autentikasi biometrik seperti pembaca sidik jari bawaan, tetapi intinya tetap struktur yang tidak mengeluarkan kunci privat dari perangkat
  • Risiko yang muncul dari kegunaan

    • Jika pengguna terbiasa menekan token keamanan setiap kali berkedip, mereka bisa tanpa sadar merespons permintaan berbahaya
    • Saat melakukan penandatanganan beruntun dan harus menekan token berulang kali, sulit benar-benar menyadari satu permintaan berkedip tambahan
    • Apple dan Microsoft menggunakan metode aplikasi autentikasi di ponsel yang menampilkan kode angka acak untuk setiap permintaan akses agar dimasukkan pengguna, tetapi ini merepotkan dan mengurangi keunggulan kegunaan token keamanan dibanding aplikasi Authy atau Google Authenticator yang memakai TOTP
  • Masalah kehilangan dan cadangan

    • Jika token keamanan hilang, kunci privat terkait hilang permanen dan tidak ada cara untuk mencadangkannya
    • Untuk menghindari risiko terkunci dari banyak akun, saat membeli token keamanan sebaiknya membeli setidaknya 2 unit dan mendaftarkannya ke layanan yang sama
    • Sebagai alternatif, ada metode cadangan/pemulihan seperti BIP 39 yang mengubah kunci privat menjadi daftar kata yang bisa dibaca manusia untuk dicatat
    • Jika kunci privat dapat keluar dari secure enclave, serangan phishing yang mendorong pengguna menuliskan daftar kata di tempat yang salah juga menjadi mungkin
    • Jika Anda sangat khawatir semua token keamanan bisa hilang, daftar kata BIP 39 dapat menjadi jalan terakhir untuk mendapatkan kembali akses ke sistem

Menggunakan token keamanan di SSH dan git

  • Menyimpan kunci privat SSH di token keamanan

    • Biasanya, menjalankan ssh-keygen akan membuat sepasang file yang berisi seluruh kunci privat
    • Untuk menaruh kunci privat di token keamanan, instal libfido2 mengikuti panduan FIDO/U2F dari Yubico, lalu jalankan ssh-keygen -t ed25519-sk saat token keamanan terpasang
    • Dalam kasus ini juga akan dibuat sepasang file, tetapi file “kunci privat” bukanlah kunci privat yang sebenarnya, melainkan handle yang menunjuk ke kunci privat di dalam token keamanan
    • Jika ssh-keygen -t ed25519-sk dijalankan lagi dengan token keamanan yang sama, file kunci privat/publik yang sama dapat dibuat di komputer mana pun, sehingga hak akses SSH berpindah bersama token keamanan, bukan bergantung pada file tertentu di komputer tertentu
  • Autentikasi git dan penandatanganan commit

    • Sekitar 90% situasi menekan token keamanan terjadi karena penggunaan git
    • Git forge mengimplementasikan autentikasi SSH untuk push dan pull, dan dengan mengunggah file id_ed25519_sk.pub yang dibuat di atas, pasangan kunci token keamanan dapat diizinkan
    • Git juga mendukung kunci SSH untuk penandatanganan commit; setelah mengikuti dokumentasi GitHub menyetel kunci penandatanganan dengan kunci SSH lalu menjalankan git config --global commit.gpgsign true, semua commit akan ditandatangani secara otomatis
    • Agar git forge mengenali commit sebagai ditandatangani oleh Anda, kunci publik harus diunggah lagi, dan kolom ini biasanya terpisah dari kolom untuk autentikasi SSH
  • Ketidaknyamanan penandatanganan commit

    • Saat me-rebase daftar commit yang panjang, semua commit harus ditandatangani ulang
    • Pada YubiKey dengan pembaca sidik jari, tingkat kegagalan pengenalan sidik jari terlalu tinggi untuk menandatangani puluhan commit secara beruntun, sehingga penggunaannya dihentikan
    • jujutsu, wrapper git yang berpusat pada “rebase/amend”, memiliki cara untuk menandatangani commit hanya pada saat push
  • Login lokal Linux dan sudo

Menggunakan secure element MacBook sebagai kunci SSH

  • Jika token keamanan terus dicolokkan ke port USB-C, ia akan menonjol seperti tuas kecil yang bisa merusak port dan token saat tersenggol atau terjatuh dengan buruk
  • Pada MacBook Air M1 keluaran 2020, secure element bawaan disetel sebagai kunci SSH mengikuti panduan dari Arian van Putten
sc_auth create-ctk-identity -l ssh -k p-256-ne -t bio
ssh-keygen -w /usr/lib/ssh-keychain.dylib -K -N ""
  • Perintah ini membuat pasangan file kunci privat/publik id_ecdsa_sk_rk, lalu file-file ini dipindahkan ke direktori ~/.ssh
  • Di sini juga, file kunci privat bukanlah kunci privat yang sebenarnya, melainkan handle untuk kunci di dalam perangkat, sehingga bentuknya dapat ditempelkan secara publik
  • Untuk menambahkan kunci publik sebagai authorized key pada server homelab, jalankan seperti berikut
ssh-copy-id -i ~/.ssh/id_ecdsa_sk_rk.pub <server nickname>
  • Setelah itu, tambahkan pengaturan berikut ke ~/.ssh/config
Host *
  IdentityFile ~/.ssh/id_ecdsa_sk_rk
  SecurityKeyProvider=/usr/lib/ssh-keychain.dylib
  • Saat menjalankan ssh <server nickname>, macOS otomatis menampilkan permintaan sidik jari sebelum login, lalu proses login SSH berjalan normal

Menandatangani commit git dengan secure element MacBook

  • Meskipun git config --global user.signingKey /Users/ahelwer/.ssh/id_ecdsa_sk_rk disetel dan file .ssh/allowed_signers diperbarui, penandatanganan commit git tidak langsung berfungsi
  • Git gagal menandatangani commit dan menampilkan kesalahan seperti device not found?
error: Signing file /var/folders/l5/5wqvq2l10p96wtdtfr6lvrvw0000gn/T//.git_signing_buffer_tmpc4uQgO
Confirm user presence for key ECDSA-SK SHA256:oQDA2SNYb2MoSQcxJVSmWyAeAWPqMp7rxliBRfi87as
Couldn't sign message: device not found?
Signing /var/folders/l5/5wqvq2l10p96wtdtfr6lvrvw0000gn/T//.git_signing_buffer_tmpc4uQgO failed: device not found?

fatal: failed to write commit object
  • Solusinya adalah menggunakan ssh-agent, bukan langsung menunjuk file di direktori ~/.ssh
  • Mengikuti tutorial di atas, pasangan kunci didaftarkan ke ssh-agent dengan perintah berikut
ssh-add -K -S /usr/lib/ssh-keychain.dylib
  • Setelah itu, pada user.signingKey bukan jalur file yang dipakai, melainkan kuncinya sendiri di ~/.gitconfig, dengan menambahkan key:: di depan isi ~/.ssh/id_ecdsa_sk_rk.pub
[user]
	name = Andrew Helwer
	signingKey = "key::sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGxFEdnIg6ppz+pQCdd1eisjOV4gxrjMv1Y4SbtdLoSm6CJCgPZ6q7lnNyuQQsdnS4/Tllsc656AQL7BO3OS47cAAAAEc3NoOg== ssh:"
  • Setelah pengaturan ini, file dapat ditandatangani dengan kunci di secure element MacBook dan didorong ke situs GitLab Pages

Hasil percobaan di Windows dan Linux

  • Eksperimen cepat juga dilakukan di laptop Windows kantor
winget install Microsoft.OpenSSH.preview
ssh-keygen -t ecdsa-sk
  • Perintah ini juga membuat pasangan file kunci privat/publik, dan saat koneksi SSH, alur login standar Windows Hello menerima salah satu dari pengenalan wajah, sidik jari, atau PIN
  • Di Linux, hal serupa tidak bisa didemokan karena tidak ada akses ke laptop yang secure element-nya terhubung setelah verifikasi keberadaan pengguna secara nyata

1 komentar

 
GN⁺ 4 jam lalu
Opini di Lobste.rs
  • Tulisan yang bagus, dan sangat bermanfaat hanya dengan menunjukkan bahwa hal seperti ini memang mungkin
    Secara pribadi aku belum menemukan versi library yang tepat untuk membuat ini berjalan, tetapi aku jadi tahu bahwa 1Password 8 menyimpan kunci SSH dengan aman dan agennya mendukung membuka kunci dengan autentikasi biometrik
    Jadi sekarang aku bisa mengerjakan git dan masuk ke host SSH hanya dengan menempelkan jari
    Panduan: https://developer.1password.com/docs/ssh/get-started/

  • Ini terlihat seperti khusus Mac

    • Di kantor aku bisa memakai laptop Windows terbaru, jadi aku membuat OpenSSH terintegrasi dengan Windows Hello seperti ini
      winget install Microsoft.OpenSSH.preview  
      ssh-keygen -t ecdsa-sk  
      
      Setelah itu semuanya bekerja seperti biasa, dan setiap kali SSH ke mana pun dengan kunci itu, aku melewati alur standar Windows Hello dan bisa memakai pemindai sidik jari, pengenalan wajah, atau PIN
      Aku belum sempat mencoba sistem Linux dengan elemen keamanan seperti itu, dan workstation Linux milikku punya TPM V1, tetapi aku tidak benar-benar tahu cara menjamin operasi penandatanganan hanya dijalankan setelah ada konfirmasi kehadiran pengguna
      Mungkin seseorang yang punya laptop Linux seperti Framework bisa mencobanya. Mungkin juga ini benar-benar bisa berjalan di Asahi
    • Kurang lebih begitu. Aku tidak tahu apakah ada lapisan emulasi TPM2 FIDO di Linux atau Windows
  • Jadi sebenarnya apa yang tersimpan di dalam file private key yang diberikan itu?

    • @wrs sudah menjawab duluan, tetapi bagian ssh: itu, yaitu aplikasinya, setara dengan origin pada passkey dan berguna saat membuat resident key per host atau domain
      Misalnya aku memakainya untuk memisahkan kunci berdasarkan penggunaan meskipun tetap di Yubikey fisik yang sama
      flags menentukan bagaimana perangkat keras harus menangani kunci [1]. Agen juga bisa menambahkan pembatasannya sendiri
      Secara teknis, blob atau ekstensi lain juga bisa disimpan di kunci FIDO, dan di tempat kerja lamaku kami pernah memakainya untuk mengirim kredensial tambahan seperti kunci publik X.509 bersama autentikasi. Caranya cukup keren
      [1]
      #define SSH_SK_USER_PRESENCE_REQD  0x01  
      #define SSH_SK_USER_VERIFICATION_REQD  0x04  
      #define SSH_SK_FORCE_OPERATION    0x10  
      #define SSH_SK_RESIDENT_KEY    0x20  
      
    • Menurut Claude, dan setelah diverifikasi dengan openssh_key_parser, strukturnya seperti ini
      Wrapper luar memiliki nilai magic openssh-key-v1\0, cipher=none, kdf=none, jadi ini bukan ciphertext
      Blob kunci publik sepanjang 74 byte berisi tipe kunci sk-ssh-ed25519@openssh.com, titik Ed25519 32 byte fdcce889…03e7852b, dan aplikasi ssh:, nilai yang memisahkan namespace kredensial FIDO antara SSH dan WebAuthn
      Bagian privatnya 248 byte dan karena cipher=none maka berupa plaintext. Di dalamnya ada nilai acak checkint1 == checkint2 == 0x46744267, tipe kunci dan kunci publik yang diulang, aplikasi ssh:, dan flags: 0x01
      Flag ini berarti USER_PRESENCE_REQUIRED, jadi perlu sentuhan tetapi tidak memerlukan PIN/verifikasi pengguna, dan ini adalah kunci non-residen
      key_handle adalah ID kredensial opak 128 byte yang dikirim ke authenticatorGetAssertion, lalu perangkat membukanya secara internal untuk memulihkan seed Ed25519
      Selain itu ada reserved kosong, komentar ahelwer@ah-mbair.local, dan padding 01 02 03
    • Jika dimasukkan ke decoder base64, hasilnya seperti ini

      openssh-key-v1����none���none����������J���sk-ssh-ed25519@openssh.com��� 盘˪<F$KW+���ssh:���FtBgFtBg���sk-ssh-ed25519@openssh.com��� 盘˪<F$KW+���ssh:���fІpF$D8"&0[X 'L=Ev ')BjM]$}rTv6Z+p9O8ݹ%V* f.|қ.%I{9 .W !D"8N ai*W�y53 �������ahelwer@ah-mbair.local
      Di sana ada versi standar kunci v1, tipe kunci sk-ssh-ed25519@openssh.com, yang entah kenapa diulang, dan nama kunci yang mudah dibaca manusia ahelwer@ah-mbair.local
      Sisanya tampaknya adalah flag OpenSSH, misalnya apakah PIN atau konfirmasi kehadiran pengguna diperlukan, dan handle GUID yang bisa dikirim OpenSSH bersama challenge ke API FIDO/U2F
      OpenSSH dapat menyimpulkan dari tipe kunci, khususnya sk, bahwa ini bukan private key sebenarnya melainkan harus memanggil elemen keamanan
      Setelah itu, ia memeriksa pengaturan SecurityKeyProvider atau variabel lingkungan SSH_SK_PROVIDER untuk mengetahui dari mana memuat library dinamis yang memungkinkan komunikasi dengan elemen keamanan tersebut

  • Artikel ini tampaknya hanya membahas SSH, tetapi adakah cara memakai Secure Enclave atau TPM di komputerkku sebagai kunci FIDO2 atau U2F?

    • Tentu saja bisa, dan seharusnya hampir bekerja dengan pengaturan bawaan
      Passkey juga merupakan salah satu bentuk pendekatan seperti ini, yaitu memakai private key terpisah untuk tiap situs web
  • Fakta ini membuatku merasa aneh bahwa dukungan untuk API key asimetris atau HMAC yang bisa diikat ke perangkat keras belum lebih umum
    Senang melihat semakin banyak spesifikasi yang mendorong arah ini, seperti WebAuthn, DBSC (Device-Bound Session Credentials), dan OAuth2 DPOP