Mundarija (33)
- Bu darsda
- 1. Nega bu kerak?
- 2. Tajriba: soxta muallif
- 3. Imzo qanday ishlaydi
- 4. SSH bilan imzolash
- 4.1 Kalit
- 4.2 Sozlash
- 4.3 Tekshirish: birinchi urinish
- 4.4 allowed_signers — kim qaysi kalit egasi
- 4.5 Begona kalit
- 4.6 Holat belgisi: %G?
- 4.7 Tag imzolash
- 4.8 Narxi
- 5. GPG — klassik yo'l
- 6. GitHub'da: Verified belgisi
- 6.1 Kalitni qo'shish
- 6.2 GitHub o'zi imzolaydigan commitlar
- 6.3 Vigilant mode va ruleset
- 7. Loyiha qadami: imzoni yoqish
- 8. Hujumchi nigohi
- 9. Ko'p uchraydigan xatolar
- 9.1 allowedSignersFile needs to be configured
- 9.2 No principal matched.
- 9.3 error: gpg failed to sign the data
- 9.4 Imzosiz verify
- 9.5 "Verified — demak xavfsiz"
- 10. Mashqlar
- 1-mashq (oson): bo'shliqlarni to'ldiring
- 2-mashq (o'rta): imzo hisoboti
- 3-mashq (qiyin): uch commit, uch hikoya
- 11. Real ishda
- Xulosa
- Manbalar
Commit imzolash: SSH va GPG imzo, Verified belgisi
Qisqacha: Git'da commit muallifi — oddiy matn:
git -c user.email=… commitbilan istalgan odamning nomidan commit qilish mumkin. Imzo buni tuzatadi: commit maxfiy kalit bilan imzolanadi, ochiq kalit bilan tekshiriladi. Eng oson yo'l — SSH kaliti:gpg.format ssh,user.signingkeyvacommit.gpgsign true. Lokal tekshiruv uchunallowed_signersfayli kerak, GitHub'da esa kalit "Signing Key" sifatida qo'shiladi va commit yonida Verified belgisi chiqadi. Kanon tajribasida begona kalit bilan imzolangan commit "No principal matched" bilan rad etildi — imzo to'g'ri, lekin kalit egasi noma'lum.
Bu darsda
user.emailbilan soxta muallif yaratib, nega imzo kerakligini ko'rasiz.- SSH kaliti bilan commit va tag imzolashni sozlaysiz.
allowed_signers,git verify-commit,log --show-signatureva%G?bilan imzoni tekshirasiz.- GPG bilan imzoni SSH bilan solishtirasiz.
- GitHub'dagi Verified belgisi, vigilant mode va "Require signed commits" qoidasini tushuntirasiz.
Oldin bilishingiz kerak: SSH kalit va GitHub autentifikatsiyasi, Git ichkaridan: obyektlar, SHA va snapshot, Tag va relizlar, Branch himoyasi va rulesets.
1. Nega bu kerak?
Git'ni o'rnatish va birinchi sozlash darsida user.name va user.email ni yozgansiz. Git ularni tekshirmaydi — bu shunchaki satrlar. Kim xohlasa, istalgan ismni yozadi.
Bu nimaga olib keladi? GitHub commit yonida email bo'yicha egasining avatarini ko'rsatadi. Begona odam taniqli dasturchining emailini yozib, PR yuborishi mumkin. Tarixda "bu kodni tajribali hamkasb yozgan" degan taassurot qoladi. Ochiq loyihalarda bu — ta'minot zanjiri hujumining eshigi: zararli kod ishonchli ism ortiga yashirinadi.
Hayotiy o'xshatish: konvertga "Jo'natuvchi: bank" deb istalgan kishi yozadi. Ishonch faqat muhr va imzodan keladi — ularni soxtalashtirish ancha qiyin. Git'da ham shunday: user.email — konvertdagi yozuv, imzo — muhr.
2. Tajriba: soxta muallif
Biz sinov repo'da (faqat lokal, hech qayerga yuborilmagan) boshqa odam nomidan commit qildik:
git -c user.name="Linus Torvalds" \
-c user.email="torvalds@linux-foundation.org" \
commit -m "chore: soxta muallif"
git log -1 --format='%h %an <%ae>'Terminalda:
f99757e Linus Torvalds <torvalds@linux-foundation.org>Git hech narsa so'ramadi. -c — bitta buyruq uchun sozlamani almashtirish. Commit tarixda Linux yaratuvchisi nomidan turibdi. Agar bu commit GitHub'ga yuborilsa, u yerda ham shu ism ko'rinadi.
Diqqat: Bu tajribani faqat o'zingizning lokal sinov repo'ngizda qiling. Birovning nomidan commit yuborish — aldash. Biz buni zaiflikni ko'rsatish uchun qildik.
3. Imzo qanday ishlaydi
Imzo g'oyasini SSH kalit darsidan bilasiz: ikki kalit, maxfiy va ochiq. Maxfiy kalit bilan imzo qo'yiladi, ochiq kalit bilan tekshiriladi. Maxfiy kalitsiz to'g'ri imzo yasab bo'lmaydi.
sequenceDiagram
participant A as Aziz (maxfiy kalit)
participant G as Git
participant T as Tekshiruvchi (ochiq kalit)
A->>G: commit + imzo
G->>T: commit obyekti, ichida gpgsig
T->>T: imzo shu matnga mosmi?
T->>T: kalit kimga tegishli?Diagrammadagi oxirgi ikki savol alohida. Birinchisi — matematika: imzo commit mazmuniga mosmi, hech narsa o'zgarmaganmi. Ikkinchisi — ishonch: bu ochiq kalit haqiqatan Azizga tegishlimi. Ikkinchi savolga Git o'zi javob bera olmaydi — unga ro'yxat kerak. Lokal'da bu allowed_signers fayli, GitHub'da — akkauntingizdagi kalitlar.
Imzo qayerda saqlanadi? Commit obyektining ichida (Git ichkaridan darsi). Kanon imzolangan commitni git cat-file -p bilan ochdi (boshi, qatorlar 80 belgida kesilgan):
tree f4b354863caa9cea99b95422c9dab70465757d87
parent 060e6046a3473415ac4d3794f73ec5aba28a23c9
author Aziz Karimov <aziz@example.com> 1793789399 +0500
committer Aziz Karimov <aziz@example.com> 1793789399 +0500
gpgsig -----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgy0AOfYBBck+EI6IDYzaxOad2CG
Hx/WHN7Iv/uxz9RaIAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
AAAAQNKOt2pBXzjHabbYcTLz5ACcgwDSO1NxWdBhYRDb/ep9+mshCDCKRhEtIoSbj/CU7Igpgsig — commit sarlavhalaridan biri. Nomi tarixiy (avval faqat GPG bor edi), ichida esa SSH imzosi. Imzo ham commit matnining qismi — demak u SHA'ga ta'sir qiladi. Imzolangan va imzosiz commit bir xil o'zgarish bilan ham turli SHA oladi.
4. SSH bilan imzolash
4.1 Kalit
Imzo uchun mavjud SSH kalitingizni ishlatsa bo'ladi. Lekin alohida kalit ochish tozaroq: kirish va imzo vazifalari ajraladi, birini almashtirish ikkinchisiga tegmaydi. SSH kalit darsidagi buyruq, boshqa fayl nomi bilan:
ssh-keygen -t ed25519 -C "aziz@example.com" -f ~/.ssh/imzo_ed25519Kanon kalitlarni faqat vaqtinchalik papkada yaratdi, tajribadan keyin o'chirdi va hech qayerga qo'shmadi. Siz esa o'z kalitingizni saqlab qolasiz — parol (passphrase) bilan.
4.2 Sozlash
To'rtta sozlama:
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/imzo_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign truegpg.format ssh— imzo turi. Sukutopenpgp(GPG).user.signingkey— qaysi kalit. GitHub hujjati SSH uchun ochiq kalit (.pub) fayli yo'lini yozishni aytadi. Imzoni Gitssh-keygendasturiga topshiradi. Biz sinagan OpenSSH 10.3p1 maxfiy kalitni yonidagi.pubsiz fayldan o'zi topdi (ssh-agentishlamagan holda ham).commit.gpgsign true— har commit imzolanadi. Bitta commit uchun:git commit -S.tag.gpgsign true— annotated taglar ham imzolanadi.
Kanon bu sozlamalarni faqat sinov repo'sida (--global siz) qildi — kompyuterning umumiy sozlamasiga tegmaslik uchun. Siz o'z kompyuteringizda --global bilan qilasiz.
4.3 Tekshirish: birinchi urinish
Imzolangan commit qilamiz va tekshiramiz. Biz ishga tushirdik:
git commit -m "feat: imzolangan commit"
git verify-commit HEADerror: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification"SSH imzosini tekshirish uchun gpg.ssh.allowedSignersFile sozlangan va mavjud bo'lishi kerak." Chiqish kodi 1. Commit imzolangan, lekin Git uni tekshira olmaydi — chunki "kalit kimniki?" degan savolga javob yo'q. Bu «Imzo qanday ishlaydi» bo'limidagi ikkinchi savol.
4.4 allowed_signers — kim qaysi kalit egasi
Fayl oddiy: har qatorda email, namespaces="git" va ochiq kalit.
KALIT=$(cat ~/.ssh/imzo_ed25519.pub)
echo "aziz@example.com namespaces=\"git\" $KALIT" \
>> ~/.ssh/allowed_signers
git config --global gpg.ssh.allowedSignersFile \
~/.ssh/allowed_signersBizning sinovdagi qatorning boshi:
aziz@example.com namespaces="git" ssh-ed25519 AAAAC3NzaC1lZDnamespaces="git" — bu kalit faqat Git imzolari uchun ishonchli (SSH imzosi boshqa maqsadlarda ham ishlatiladi). Endi tekshiruv:
git verify-commit HEADGood "git" signature for aziz@example.com with ED25519 key SHA256:ULbt2THx1iWzjHN07XfLhYaXu+qY11d5jxfWD3RMh98"aziz@example.com uchun yaxshi imzo, ED25519 kaliti, barmoq izi …". Chiqish kodi 0. SHA256:… — kalitning barmoq izi (fingerprint): uzun kalitning qisqa, solishtirish oson ko'rinishi. Sizda u boshqa bo'ladi.
Tarixda imzolarni ko'rish:
git log -1 --show-signaturecommit 8a96aa2c461e79fc4023cff3bb55daa9115b1660 (HEAD -> main)
Good "git" signature for aziz@example.com with ED25519 key SHA256:ULbt2THx1iWzjHN07XfLhYaXu+qY11d5jxfWD3RMh98
Author: Aziz Karimov <aziz@example.com>
Date: Wed Nov 4 10:05:00 2026 +0500
feat: imzolangan commit4.5 Begona kalit
Endi eng qiziq holat. Kimdir o'z kaliti bilan commitni imzoladi, lekin muallif sifatida Azizning emailini yozdi:
git -c user.signingkey=../kalit/begona.pub \
commit -m "fix: begona imzo"
git verify-commit HEADBiz ishga tushirdik:
Good "git" signature with ED25519 key SHA256:tfdQYXchG1IA6g+4HEF+pCuPcK70AMWwiLKM9NDAqO0
No principal matched.Birinchi qator "Good" deydi — imzo matematik jihatdan to'g'ri, commit o'zgarmagan. Lekin ikkinchi qator: "Hech qaysi egasi mos kelmadi" — bu kalit allowed_signers da yo'q. Chiqish kodi 1. Git aldovni ushladi: email — Azizniki, kalit — Azizniki emas.
4.6 Holat belgisi: %G?
Ko'p commitni birdaniga ko'rish uchun git log formatida %G? bor. Kanon tarixining xulosasi:
git log --format='%h %G? %an — %s'd05b0ed U Aziz Karimov — fix: begona imzo
2daa376 G Aziz Karimov — feat: imzolangan commit
060e604 N Linus Torvalds — chore: soxta muallif| Belgi | Ma'nosi |
|---|---|
G |
yaxshi imzo, kalit ishonchli |
U |
imzo to'g'ri, lekin kalit egasi noma'lum |
N |
imzo yo'q |
B |
imzo buzuq — commit o'zgartirilgan |
E |
tekshirib bo'lmadi (masalan, allowed_signers yo'q) |
Git hujjatida yana uchta belgi bor — X, Y, R: imzo yaxshi, lekin imzo yoki kalit muddati o'tgan, yoki kalit bekor qilingan. Ular asosan GPG kalitlarida uchraydi.
Uch qator — uch xil hikoya. N — oddiy imzosiz commit (sozlashdan oldingi). G — haqiqiy Aziz. U — Aziz nomidan, lekin boshqa kalit bilan. Faqat ism va emailga qarasangiz, U va G bir xil ko'rinadi.
4.7 Tag imzolash
Relizlar uchun tag imzosi ayniqsa muhim (CHANGELOG va reliz darsidagi v4.0.1): "bu reliz haqiqatan jamoadan" degan isbot. tag.gpgsign true bo'lsa, git tag -a o'zi imzolaydi; bitta tag uchun — git tag -s. Tekshiruv:
git tag -m "v1.0.0" v1.0.0 HEAD~1
git tag -v v1.0.0Biz ishga tushirdik:
Good "git" signature for aziz@example.com with ED25519 key SHA256:ULbt2THx1iWzjHN07XfLhYaXu+qY11d5jxfWD3RMh98
object 8a96aa2c461e79fc4023cff3bb55daa9115b1660
type commit
tag v1.0.0
tagger Aziz Karimov <aziz@example.com> 1793769000 +0500
v1.0.0Imzo qatori va tag obyektining mazmuni. git verify-tag v1.0.0 ham xuddi shunday tekshiradi.
4.8 Narxi
Har commitda imzo — maxfiy kalit bilan bitta hisob. Kanon 20 ta commitni imzo bilan va imzosiz o'lchadi: 10.5 s va 7.9 s (bitta mashina, shovqinli — nisbat taxminiy). Har commitga ~0.13 s qo'shimcha. Kundalik ishda sezilmaydi.
Haqiqiy narx boshqa joyda: kalitni saqlash. Maxfiy kalit o'g'irlansa, o'g'ri sizning nomingizdan "Verified" commit qiladi. Kalitga parol qo'ying, uni hech qachon repo'ga, chatga yoki bulutdagi papkaga qo'ymang.
Tekshirib ko'ring: Imzolangan commitni
git commit --amendbilan tahrirladingiz, lekin shu safar-c commit.gpgsign=falsebilan.%G?nima ko'rsatadi va nega?
Javob
N — imzosiz. Amend yangi commit obyekti yaratadi, eski imzo eski obyektda qoldi. Biz sinab ko'rdik: 9c9dd23 N fix: begona imzo. Imzo commitga "yopishtirilmaydi" — u har yangi obyekt uchun qaytadan qo'yiladi. Rebase, amend, cherry-pick — hammasi yangi commit, shuning uchun commit.gpgsign true bo'lsa, ular sizning kalitingiz bilan qayta imzolanadi. Tarixni butunlay qayta yozadigan git filter-repo esa imzolarni qayta qo'ymaydi — olib tashlaydi. Buni keyingi darsda ko'rasiz.
5. GPG — klassik yo'l
SSH imzosi Git'ga ancha keyin qo'shilgan: GitHub hujjatiga ko'ra, SSH imzoni tekshirish uchun Git 2.34 yoki undan yangisi kerak. Undan oldin yagona yo'l GPG (GnuPG, OpenPGP standarti) edi. Git uchun ishlashi bir xil: gpg.format sukut — openpgp, user.signingkey — GPG kalit ID'si.
Taqqoslash uchun GPG bilan ham sinadik (GnuPG 2.4.9, kalit vaqtinchalik papkada, keyin o'chirildi). Kalit ro'yxati:
sec ed25519/67657B97D728F83C 2026-11-04 [SC]
F61A3F06B084CED623B949E167657B97D728F83C
uid [ultimate] Aziz Karimov <aziz@example.com>git commit -S va git verify-commit HEAD:
gpg: Signature made Wed Nov 4 17:52:49 2026 WAST
gpg: using EDDSA key F61A3F06B084CED623B949E167657B97D728F83C
gpg: Good signature from "Aziz Karimov <aziz@example.com>" [ultimate]WAST — Git Bash'dagi gpg vaqt zonasini noto'g'ri qisqartmada ko'rsatdi; vaqt o'zi to'g'ri (Toshkent). %G? — G.
| SSH | GPG | |
|---|---|---|
| Kalit | sizda allaqachon bor | alohida yaratiladi |
| Kim ekani | allowed_signers yoki GitHub akkaunti |
kalit ichidagi uid, ishonch tarmog'i |
| Muddat, bekor qilish | allowed_signers da valid-after / valid-before; kalitni ro'yxatdan o'chirasiz |
kalit ichidagi muddat, revocation sertifikati |
| Murakkablik | kam | ko'p (agent, keyserver) |
Kanon SSH ni tanladi: kalit 07-qismdan beri bor, sozlash to'rt qator. GPG'ning ustunligi — muddat va rasmiy bekor qilish kalitning o'zida yuradi, har tekshiruvchining ro'yxatida emas. Ular ko'p yillik ochiq loyihalarda, paket imzolashda kerak bo'ladi.
Bizning tajribada bitta tuzoq chiqdi: gpg'ni maxsus papka (GNUPGHOME) bilan ishlatganda Windows'dagi git u yo'lni gpg'ga noto'g'ri uzatdi va error: gpg failed to sign the data oldik. Odatdagi sukut papka bilan bu muammo yo'q. Xato chiqsa, avval gpg --list-secret-keys kalitni ko'rsatayotganini tekshiring.
6. GitHub'da: Verified belgisi
6.1 Kalitni qo'shish
GitHub imzoni tekshirishi uchun ochiq kalitingizni bilishi kerak. SSH kalit darsida kirish kaliti "Authentication Key" sifatida qo'shilgan edi. Imzo kaliti xuddi shu sahifaga, boshqa tur bilan qo'shiladi (docs.github.com, "Adding a new SSH key to your GitHub account", 2026-11-04 da o'qildi; o'zimiz sinamadik):
- Istalgan GitHub sahifasida o'ng yuqoridagi profil rasmi → Settings.
- Chap menyuning Access bo'limida SSH and GPG keys.
- New SSH key, Title ga nom (masalan, "Noutbuk — imzo").
- Kalit turi — imzo (Signing Key); hujjat "authentication or signing" deb yozadi.
- Key maydoniga
imzo_ed25519.pubmazmunini qo'yib, Add SSH key. GitHub parolni yoki 2FA kodini qayta so'rashi mumkin.
Bitta kalitni ham kirish, ham imzo uchun ishlatmoqchi bo'lsangiz, hujjatga ko'ra uni ikki marta — ikki tur bilan qo'shasiz.
Kalit qo'shilgach, shu kalit bilan imzolangan commitlar yonida Verified chiqadi: GitHub imzoni akkauntingizdagi ochiq kalit bilan tekshiradi. Commitdagi email akkauntingizda tasdiqlangan bo'lsin — hujjat buni committer emaili uchun tavsiya qiladi. Kanon kalitni akkauntga qo'shmadi — Verified belgisini sinov reposida ko'rmadik.
6.2 GitHub o'zi imzolaydigan commitlar
Bir qiziq topilma bor. Sinov reposidagi ikki commitni GitHub API'dan so'radik (faqat o'qish; repo nomi va muallif login ga almashtirildi; ikkinchi qator — xuddi shu buyruq 9c395ca uchun):
gh api repos/login/vazifalar-api/commits/22a1226 \
--jq '{sha: .sha[0:7], verified: .commit.verification.verified,
reason: .commit.verification.reason,
committer: .commit.committer.name}'{"committer":"GitHub","reason":"valid","sha":"22a1226","verified":true}
{"committer":"login","reason":"unsigned","sha":"9c395ca","verified":false}22a1226 — PR #9 ning squash commiti. Uni GitHub'ning o'zi yaratgan va o'z kaliti bilan imzolagan: committer — "GitHub", Verified. Hujjatga ko'ra, veb interfeysda yaratilgan commitlarni GitHub GPG kaliti bilan imzolaydi; ochiq kaliti — https://github.com/web-flow.gpg. 9c395ca — terminaldan to'g'ridan push qilingan import commiti: imzosiz. Demak, Jamoa workflow'lari darsidagi squash merge'lar main da avtomatik "Verified" bo'ladi. Lekin bu imzo "GitHub bu commitni yaratdi" deydi, "Aziz yozdi" demaydi. PR ichidagi commitlarning imzosi alohida tekshiriladi.
6.3 Vigilant mode va ruleset
Yana ikki imkoniyat (docs.github.com, sinalmagan, 2026-11):
- Vigilant mode — Settings → SSH and GPG keys sahifasida, "Vigilant mode" ostidagi "Flag unsigned commits as unverified" belgisi. Yoqilsa, siz committer yoki muallif bo'lgan imzosiz commitlar "Unverified" deb belgilanadi. Demak, kimdir emailingizni yozib imzosiz commit qilsa, u ishonchli ko'rinmaydi (bu — hujjatdan xulosa, sinalmagan).
- Require signed commits — ruleset qoidasi (Branch himoyasi darsidagi ro'yxatda). Himoyalangan branch'ga faqat tasdiqlangan imzoli commitlar tushadi.
Birinchisi — sizning nomingizni himoya qiladi, ikkinchisi — repo'ni.
7. Loyiha qadami: imzoni yoqish
Bu dars — tajriba darsi: vazifalar-api kodi o'zgarmaydi va commit yo'q. Lekin bundan keyingi commitlaringiz imzolansin:
- Imzo kaliti yarating («Kalit» bo'limi) va unga parol qo'ying.
- To'rtta
git config --globalsozlamasini yozing vaallowed_signersyarating. - Bo'sh commit bilan sinang:
git commit --allow-empty -m "chore: imzo sinovi", keyingit log -1 --show-signature— "Good" chiqishi kerak. - Sinov commitini bekor qiling:
git reset --hard HEAD~1(reset darsi; faqat push qilinmagan bo'lsa). - GitHub'ga kalitni Signing Key sifatida qo'shing va xohlasangiz vigilant mode'ni yoqing.
Kanon bu qadamlarning 1–3 tasini lokal sinov repo'sida bajardi. 5-qadam sinalmagan — Verified belgisini o'zingiz birinchi bo'lib ko'rasiz.
8. Hujumchi nigohi
Imzo qaysi hujumlarga qarshi turadi va qaysilariga — yo'q?
- Soxta muallif. Hujumchi taniqli dasturchining emailini yozib, PR yuboradi. Imzosiz repoda u ishonchli ko'rinadi. Vigilant mode yoqilgan bo'lsa — commit "Unverified", ruleset'da "Require signed commits" bo'lsa —
mainga umuman tushmaydi. - Begona kalit. Hujumchi o'z kalitini yaratib, commitni imzolaydi va emailni sizniki deb yozadi. Imzo matematik jihatdan to'g'ri — lekin
allowed_signersda va GitHub akkauntingizda bu kalit yo'q. Natija:Uva "No principal matched". Bu holatni biz o'z ko'zimiz bilan ko'rdik. - O'g'irlangan kalit. Bunga imzo qarshi tura olmaydi: o'g'ri sizning kalitingiz bilan "Verified" commit qiladi. Himoya — kalitdagi parol, uni repo va bulutga qo'ymaslik, yo'qolsa GitHub'dan darhol o'chirish.
- Ishonchli muallif, zararli kod. Imzo kodni tekshirmaydi. Shuning uchun review va testlar baribir majburiy.
9. Ko'p uchraydigan xatolar
9.1 allowedSignersFile needs to be configured
error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verificationImzo bor, tekshiruv ro'yxati yo'q. Davosi: allowed_signers fayli va gpg.ssh.allowedSignersFile sozlamasi. GitHub'da bu kerak emas — u kalitlarni akkauntdan oladi.
9.2 No principal matched.
Kalit allowed_signers da yo'q yoki undagi email commitdagi bilan mos emas. O'z commitingizda chiqsa — fayldagi email va user.email ni solishtiring. Birovnikida chiqsa — ehtiyot bo'ling: kimdir begona kalit bilan imzolagan.
9.3 error: gpg failed to sign the data
Commit umuman yaratilmadi:
error: gpg failed to sign the data:
...
fatal: failed to write commit objectSabablari: kalit fayli yo'li noto'g'ri, GPG kaliti topilmadi, gpg dasturi ishga tushmadi. Davosi: git config user.signingkey ni tekshiring; SSH uchun — .pub fayl mavjudmi.
9.4 Imzosiz verify
Imzosiz commitga git verify-commit hech narsa yozmaydi, faqat chiqish kodi 1 qaytaradi (biz sinadik). Skriptda kodni tekshiring, matnni emas.
9.5 "Verified — demak xavfsiz"
Verified faqat kim yozganini aytadi, nima yozilganini emas. Imzolangan commitda ham xato yoki zararli kod bo'lishi mumkin. Imzo code review o'rnini bosmaydi.
10. Mashqlar
Mashqlar kurs/mashqlar/32/04-imzo/ da. 2-mashq yechimi Node 24.21.0 da, 3-mashq yechimi Git 2.54.0 va OpenSSH 10.3p1 da tekshirilgan (biz ishga tushirdik).
1-mashq (oson): bo'shliqlarni to'ldiring
- SSH bilan imzolash uchun
gpg.formatqiymati — - Har commitni avtomatik imzolaydigan sozlama —
commit. - Imzo to'g'ri, lekin kalit egasi noma'lum bo'lsa
%G?belgisi — - Imzolangan tagni tekshiradigan buyruq —
git tag - O'z nomingizdagi imzosiz commitlarni "Unverified" qiladigan GitHub sozlamasi —
Yechim
- ssh — sukut
openpgp. - gpgsign — bitta commit uchun
git commit -S. - U — "No principal matched": kalit
allowed_signersda yo'q. - -v — yoki
git verify-tag. - vigilant mode — "Flag unsigned commits as unverified".
2-mashq (o'rta): imzo hisoboti
imzoHisoboti(qatorlar) funksiyasini yozing. Kirish — git log --format='%h %G? %an — %s' chiqishining qatorlari. Funksiya har holatdan nechta borligini (soni) va G bo'lmagan commitlar ro'yxatini (diqqat, ko'rinishi "hash: ma'no") qaytarsin. Ma'nolar «Holat belgisi: %G?» bo'limidagi jadvaldan. Ishora: qatorni split(" ") bilan bo'lsangiz, birinchi ikki bo'lak — hash va belgi (Massiv destructuring).
Yechim
const MANO = {
G: "yaxshi", U: "kalit egasi noma'lum", N: "imzosiz",
B: "buzuq", E: "tekshirib bo'lmadi",
};
function imzoHisoboti(qatorlar) {
const soni = {};
const diqqat = [];
for (const q of qatorlar) {
const [hash, holat] = q.split(" ");
soni[holat] = (soni[holat] ?? 0) + 1;
if (holat !== "G") {
diqqat.push(`${hash}: ${MANO[holat] ?? holat}`);
}
}
return { soni, diqqat };
}
console.log(imzoHisoboti([
"d05b0ed U Aziz Karimov — fix: begona imzo",
"2daa376 G Aziz Karimov — feat: imzolangan commit",
"060e604 N Linus Torvalds — chore: soxta muallif",
]));Konsolda:
{
soni: { U: 1, G: 1, N: 1 },
diqqat: [ "d05b0ed: kalit egasi noma'lum", '060e604: imzosiz' ]
}Kirish — kanon tarixining haqiqiy xulosasi. Ikki commit diqqat talab qiladi. Node apostrofli satrni qo'shtirnoqda, qolganini bittalik tirnoqda chiqardi — ma'nosi bir xil. Bunday hisobot reliz oldidan foydali: "oxirgi tagdan beri imzosiz commit bormi?" — git log v4.0.0..HEAD --format=… chiqishini shu funksiyaga bering.
3-mashq (qiyin): uch commit, uch hikoya
Vaqtinchalik papkada butun tajribani o'zingiz takrorlang: ikki kalit (aziz va begona), allowed_signers faqat Aziz kaliti bilan, uchta commit — imzosiz, Aziz kaliti bilan, begona kalit bilan. Keyin %G? va oxirgi ikki commitning verify-commit natijasini chiqaring. Global sozlamaga tegmang: hammasi shu repo'ning sozlamasi bo'lsin. Oxirida papkani o'chiring — kalitlar ham ketadi.
Ishora: bitta commit uchun kalitni git commit -S --gpg-sign=<ochiq-kalit-fayli> bilan berish mumkin. Barmoq izi har safar boshqa — uni sed 's/SHA256:.*/SHA256:…/' bilan qisqartiring. ${PIPESTATUS[0]} — quvurdagi birinchi buyruqning chiqish kodi (Bisect darsidagi skriptlar kabi).
Yechim
mkdir imzo-sinov && cd imzo-sinov
ssh-keygen -q -t ed25519 -N "" -C "aziz@example.com" -f aziz
ssh-keygen -q -t ed25519 -N "" -C "begona" -f begona
echo "aziz@example.com namespaces=\"git\" $(cat aziz.pub)" \
> allowed_signers
git init -q -b main repo && cd repo
git config user.name "Aziz Karimov"
git config user.email "aziz@example.com"
git config gpg.format ssh
git config gpg.ssh.allowedSignersFile ../allowed_signers
echo 1 > a.txt && git add a.txt
git commit -q -m "chore: imzosiz"
echo 2 > b.txt && git add b.txt
git commit -q -S --gpg-sign=../aziz.pub -m "feat: o'z kalitim"
echo 3 > c.txt && git add c.txt
git commit -q -S --gpg-sign=../begona.pub -m "fix: begona kalit"
git log --format='%G? %s'
for r in HEAD~1 HEAD; do
git verify-commit $r 2>&1 | sed 's/SHA256:.*/SHA256:…/'
echo "exit ${PIPESTATUS[0]}"
done
cd ../.. && rm -rf imzo-sinovBiz ishga tushirdik:
U fix: begona kalit
G feat: o'z kalitim
N chore: imzosiz
Good "git" signature for aziz@example.com with ED25519 key SHA256:…
exit 0
Good "git" signature with ED25519 key SHA256:…
No principal matched.
exit 1Uch commit — uch hikoya: N (imzo yo'q), G (Aziz), U (imzo bor, lekin egasi ro'yxatda yo'q). -N "" — kalitga parol qo'ymaslik; bu faqat bir martalik sinov uchun. Haqiqiy kalitingizga parol qo'ying. --gpg-sign ga kalit fayli berilgani uchun user.signingkey kerak bo'lmadi — bitta repo'da ikki kalitni almashtirib ko'rishning qulay yo'li.
11. Real ishda
- Qayerda uchraydi: ko'p ochiq loyihalar va kompaniyalarda himoyalangan branch'ga faqat imzolangan commit tushadi. Paket kelib chiqishini isbotlash (npm provenance) ham shu g'oyaga tayanadi: "bu paketni aynan shu repo'dan, shu CI yig'gan".
- Kalit gigiyenasi: kalitga parol; bitta qurilma — bitta kalit; noutbuk yo'qolsa, GitHub'dan kalitni darhol o'chirish.
- Intervyu savollari: "Commitni nega imzolash kerak?", "Verified belgisi nimani kafolatlaydi va nimani kafolatlamaydi?", "SSH va GPG imzo farqi?"
Xulosa
user.namevauser.email— tekshirilmaydigan matn: istalgan kishi istalgan nomdan commit qila oladi.- Imzo — maxfiy kalit bilan qo'yiladi, ochiq kalit bilan tekshiriladi; u commit obyektining ichida (
gpgsig). - SSH imzo:
gpg.format ssh,user.signingkey,commit.gpgsign,tag.gpgsign; lokal tekshiruvgaallowed_signerskerak. %G?:G— yaxshi,U— kalit egasi noma'lum,N— imzosiz; "No principal matched" — begona kalit.- GitHub: kalit "Signing Key" sifatida qo'shiladi → Verified; vigilant mode — nomingizni, ruleset — repo'ni himoya qiladi.
- Verified — kim yozganini aytadi, kod xavfsizligini emas.
Keyingi dars: Tarixni qayta yozish va sirlarni tozalash — .env tarixga tushib qolsa nima qilish kerak: git filter-repo, --fixup va nega tozalash kalitni almashtirish o'rnini bosmaydi.
Manbalar
- Git hujjati — git-config (
gpg.format,gpg.ssh.allowedSignersFile,commit.gpgSign): https://git-scm.com/docs/git-config - Git hujjati — git-verify-commit: https://git-scm.com/docs/git-verify-commit
- Git hujjati — pretty formats (
%G?): https://git-scm.com/docs/pretty-formats - OpenSSH — ssh-keygen (ALLOWED SIGNERS): https://man.openbsd.org/ssh-keygen#ALLOWED_SIGNERS (sinalmagan, 2026-11)
- GitHub Docs — About commit signature verification: https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification (sinalmagan, 2026-11)
- GitHub Docs — Telling Git about your signing key (SSH): https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key (sinalmagan, 2026-11)
- GitHub Docs — Displaying verification statuses for all of your commits (vigilant mode): https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits (sinalmagan, 2026-11)
- Kanon tajribasi (IlmHamroh, 2026-11-04): Git 2.54.0, OpenSSH 10.3p1, GnuPG 2.4.9; kalitlar vaqtinchalik papkada, tajribadan keyin o'chirildi, GitHub'ga qo'shilmadi. Soxta muallif,
allowed_signers, begona kalit, tag, amend, GPG chiqishlari, sinov reposidagi commitlarning API holati va mashq yechimlari — biz ishga tushirdik (2026-11-04).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!