Аюулгүй байдал ба Криптограф

Өнгөрсөн жилийн аюулгүй байдал ба нууцлалын хичээл нь таныг компьютерын хэрэглэгч байхын хувьд хэрхэн илүү аюулгүй байх вэ гэдэгт анхаарлаа хандуулсан. Харин энэ жил бид Git-д хэш функц ашиглах, эсвэл SSH-д түлхүүр гаргаж авах функц болон симметрик, асимметрик криптосистемүүдийг ашиглах зэрэг энэ хичээлээр үзсэн хэрэгслүүдийг ойлгоход хэрэгтэй аюулгүй байдал, криптографын ойлголтуудад анхаарлаа хандуулах болно.

Энэ хичээл нь компьютерын системийн аюулгүй байдлын 6.858 эсвэл криптографын 6.857 болон 6.875 гэх мэт илүү гүнзгий, системтэй хичээлийг орлохгүй. Аюулгүй байдлын талаар албан ёсны сургалтад хамрагдаагүй бол аюулгүй байдлын ажил бүү хийгээрэй. Хэрэв та мэргэжилтэн биш бол өөрийн крипто шийдлийг бүү зохио. Энэ зарчим системийн аюулгүй байдалд ч мөн адил хамаарна.

Энэ хичээл нь криптографын үндсэн ойлголтуудыг маш энгийн бөгөөд практик түвшинд тайлбарлах болно. Хичээл маань танд аюулгүй систем эсвэл криптографын протокол зохиохыг зааж чадахгүй ч, таны өдөр тутам хэрэглэдэг программ ба протоколуудын ажиллагааг ерөнхийд нь ойлгоход тусална гэж найдаж байна.

Энтропи

Энтропи бол санамсаргүй байдлын хэмжүүр юм. Энэ нь жишээлбэл, нууц үгийн найдвартай байдлыг тодорхойлоход хэрэгтэй байдаг.

XKCD 936: Password Strength

Дээрх XKCD комик-т үзүүлснээр “correcthorsebatterystaple” гэх мэт нууц үг нь “Tr0ub4dor&3” гэх мэт нууц үгнээс хамаагүй илүү аюулгүй байдаг. Гэхдээ үүнийг хэрхэн тоон үзүүлэлтээр илэрхийлэх вэ?

Энтропийг бит-ээр хэмжих бөгөөд боломжит үр дүнгүүдийн олонлогоос ижил магадлалтайгаар сонголт хийхэд энтропи нь log_2(боломжийн тоо)-той тэнцүү байна. Шударга зоос шидэхэд 1 битийн энтропи үүснэ. Зургаан талтай шоо орхиход ~2.58 битийн энтропи үүснэ.

Та халдагч этгээд нууц үг үүсгэсэн загварыг нь мэддэг боловч тухайн нууц үгийг сонгоход ашигласан санамсаргүй байдлыг, тухайлбал шоо хаях үйлдлийг мэдэхгүй гэж тооцох хэрэгтэй.

Хэдэн битийн энтропи хангалттай вэ? Энэ нь таны аюулын загвараас хамаарна. Онлайн таалт хийх эрсдэлээс хамгаалахад XKCD комикст дурдсанчлан ~40 битийн энтропи хангалттай. Харин офлайн таалт хийх эрсдэлээс хамгаалахад 80 бит буюу түүнээс дээш хэмжээтэй илүү хүчтэй нууц үг шаардлагатай болно.

Хэш функцүүд

Криптограф хэш функц нь дурын хэмжээтэй өгөгдлийг тогтмол хэмжээтэй утга руу хөрвүүлдэг бөгөөд тодорхой тусгай шинж чанартай байдаг. Хэш функцийн ерөнхий тодорхойлолт нь дараах байдалтай байна:

hash(value: array<byte>) -> vector<byte, N>  (тогтмол N хэмжээтэй)

Хэш функцийн нэг жишээ бол Git-д ашиглагддаг SHA1 юм. Энэ нь дурын хэмжээтэй оролтыг 160 битийн гаралт руу (үүнийг 40 ширхэг арван зургаатын тэмдэгтээр дүрсэлж болно) хөрвүүлдэг. Бид sha1sum командыг ашиглан оролтонд SHA1 хэш тооцоолж туршиж үзэж болно:

$ printf 'hello' | sha1sum
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
$ printf 'hello' | sha1sum
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
$ printf 'Hello' | sha1sum
f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0

Ерөнхий түвшинд хэш функцийг буцааж тооцоолоход маш хэцүү, санамсаргүй мэт харагддаг, гэхдээ нэг оролтонд үргэлж ижил гаралт өгдөг детерминистик функц гэж ойлгож болно. Энэ нь хэш функцийн хамгийн тохиромжтой загвар буюу random oracle юм. Хэш функц нь дараах шинж чанаруудтай:

Анхааруулга: тодорхой зорилгоор ашиглаж болох ч SHA-1-ийг криптографын хувьд хүчтэй хэш функц гэж үзэхээ больсон. Та криптограф хэш функцүүдийн амьдралын мөчлөг-ийн хүснэгтийг сонирхож магадгүй юм. Гэсэн хэдий ч тодорхой хэш функцуудыг санал болгох нь энэ хичээлийн хамрах хүрээнээс гадуур юм. Хэрэв та үүнийг бодитоор ашиглах ажил хийж байгаа бол аюулгүй байдал/криптографын албан ёсны сургалтад хамрагдах шаардлагатай.

Хэрэглээ

Гарын үсэг зурах/баталгаажуулах функц нь бодит амьдрал дээрх цахим гарын үсэгтэй адил хуурамчаар үйлдэх боломжгүй шинж чанартай. Ямар ч зурвасын хувьд хувийн түлхүүргүйгээр verify функцэд үнэн гэж буцаах гарын үсэг үүсгэх нь тооцооллын хувьд бараг боломжгүй юм. Мөн мэдээж хэрэг verify(message, sign(message, private key), public key) = true байх зөв ажиллагааны үндсэн шинж чанарыг хангана.

Хэрэглээ

Түлхүүр түгээх асуудал

Асимметрик криптограф нь гайхалтай хэрэгсэл боловч нийтийн түлхүүрийг бусдад найдвартай хүргэх, тухайн түлхүүрийг бодит хүмүүстэй холбож баталгаажуулах нь том асуудал байдаг. Үүнийг шийдэх олон арга бий. Signal-ийн шийдэл бол энгийн: анхны хэрэглээнд итгэх бөгөөд өөр сувгаар нийтийн түлхүүрийг тулгахыг дэмждэг, өөрөөр хэлбэл найзынхаа “аюулгүй байдлын дугаарыг” биеэр уулзахдаа шалгадаг. PGP нь итгэлцлийн сүлжээ буюу web of trust гэх өөр шийдлийг ашигладаг. Keybase нь нийгмийн баталгаа дээр суурилсан өөр нэг сонирхолтой шийдлийг ашигладаг. Загвар бүр өөрийн гэсэн давуу талтай; бид Keybase-ийн загварыг илүүд үздэг.раф гэж бодоход хамгийн түрүүнд санаанд ордог ойлголт байх. Симметрик криптограф нь үүнийг дараах функцүүдийн тусламжтайгаар гүйцэтгэдэг:

keygen() -> key  (энэ функц нь санамсаргүй утга ашигладаг)

encrypt(plaintext: array<byte>, key) -> array<byte>  (шифрлэгдсэн бичвэр - ciphertext)
decrypt(ciphertext: array<byte>, key) -> array<byte>  (энгийн бичвэр - plaintext)

Шифрлэх функц нь түлхүүргүйгээр гаралтын шифрлэгдсэн бичвэрээс (ciphertext) оролтын энгийн бичвэрийг (plaintext) олохыг тооцооллын хувьд хэцүү болгодог шинж чанартай. Буцааж тайлах функц нь decrypt(encrypt(m, k), k) = m байх зөв ажиллагааны үндсэн шинж чанарыг хангадаг.

Өнөө үед өргөн хэрэглэгдэж буй симметрик криптосистемийн жишээ бол AES юм.

Хэрэглээ

Асимметрик криптограф

“Асимметрик” гэдэг нь хоёр өөр үүрэг бүхий хоёр түлхүүр байгааг илэрхийлнэ. Хувийн түлхүүрийг (private key) нэрнийх нь адилаар нууцлах ёстой бөгөөд харин нийтийн түлхүүрийг (public key) хэнд ч нээлттэй хуваалцаж болох бөгөөд энэ нь аюулгүй байдалд сөргөөр нөлөөлөхгүй (симметрик криптограф шиг түлхүүрээ хуваалцахаас өөр). Асимметрик криптосистемүүд нь шифрлэх/тайлах болон гарын үсэг зурах/баталгаажуулах дараах функцүүдийг олгодог:

keygen() -> (public key, private key)  (энэ функц нь санамсаргүй утга ашигладаг)

encrypt(plaintext: array<byte>, public key) -> array<byte>  (шифрлэгдсэн бичвэр - ciphertext)
decrypt(ciphertext: array<byte>, private key) -> array<byte>  (энгийн бичвэр - plaintext)

sign(message: array<byte>, private key) -> array<byte>  (цахим гарын үсэг - signature)
verify(message: array<byte>, signature: array<byte>, public key) -> bool  (гарын үсэг хүчин төгөлдөр эсэх)

Шифрлэх/тайлах функцүүд нь симметрик системийн адил шинж чанартай. Зурвасыг нийтийн түлхүүрээр шифрлэх боломжтой. Гаралтын шифрлэгдсэн бичвэрээс (ciphertext) хувийн түлхүүргүйгээр энгийн бичвэрийг (plaintext) олох нь тооцооллын хувьд хэцүү байна. Буцааж тайлах функц нь decrypt(encrypt(m, public key), private key) = m байх зөв ажиллагааны үндсэн шинж чанарыг хангадаг.

Симметрик болон асимметрик шифрлэлтийг физик цоожтой зүйрлэж болно. Симметрик систем нь хаалганы цоож шиг юм: түлхүүртэй хэн ч хаалгыг цоожилж, бас нээж чадна. Асимметрик шифрлэлт нь түлхүүртэй дүүжлэн цоожтой адил юм. Та цоожийг (нийтийн түлхүүр) нээлттэйгээр бусдад өгч болох ба тэд зурвасаа хайрцагт хийгээд цоожилж (шифрлэж) чадна, харин цоожийг зөвхөн та өөртөө авч үлдсэн түлхүүрээрээ (хувийн түлхүүр) нээх боломжтой.

Гарын үсэг зурах/баталгаажуулах функц нь бодит амьдрал дээрх цахим гарын үсэгтэй адил хуурамчаар үйлдэх боломжгүй шинж чанартай. Ямар ч зурвасын хувьд хувийн түлхүүргүйгээр verify функцэд үнэн (true) гэж буцаах гарын үсэг (signature) үүсгэх нь тооцооллын хувьд бараг боломжгүй юм. Мөн мэдээж хэрэг verify(message, sign(message, private key), public key) = true байх зөв ажиллагааны үндсэн шинж чанарыг хангана.

Хэрэглээ

Түлхүүр түгээх асуудал

Асимметрик криптограф нь гайхалтай хэрэгсэл боловч нийтийн түлхүүрийг бусдад найдвартай хүргэх, тухайн түлхүүр нь бодит хүнийх мөн эсэхийг баталгаажуулах (нийтийн түлхүүрийг бодит хүмүүстэй холбох) том асуудал байдаг. Үүнийг шийдэх олон арга бий. Signal-ийн шийдэл бол энгийн: анхны хэрэглээнд итгэх (trust on first use) бөгөөд өөр сувгаар (out-of-band) нийтийн түлхүүрийг тулгахыг дэмждэг (танай найзынхаа “аюулгүй байдлын дугаарыг” биеэр уулзахдаа шалгадаг). PGP нь итгэлцлийн сүлжээ (web of trust) гэх өөр шийдлийг ашигладаг. Keybase нь нийгмийн баталгаа (social proof) дээр суурилсан өөр нэг сонирхолтой шийдлийг ашигладаг. Загвар бүр өөрийн гэсэн давуу талтай; бид (багш нар) Keybase-ийн загварт дуртай.

Бодит жишээнүүдийн судалгаа

Нууц үг менежерүүд

Энэ бол хүн бүрийн ашиглахыг оролдох ёстой маш чухал хэрэгсэл юм (жишээ нь KeePassXC, pass, болон 1Password). Нууц үг менежерүүд нь вэбсайт бүрд санамсаргүй үүсгэсэн өндөр энтропи бүхий өөр өөр нууц үг ашиглах боломжийг олгодог бөгөөд тэдгээр нууц үгсийг нэг дор KDF-ээр үүсгэсэн түлхүүрээр симметрик шифрлэлт ашиглан хадгалдаг.

Нууц үг менежер ашигласнаар та нэг нууц үгээ олон газар ашиглахаас сэргийлж (нэг вэбсайт хакердагдахад бусад хаяг тань хамгаалагдаж үлдэнэ), өндөр энтропи бүхий нууц үг хэрэглэж, өөрөө зөвхөн ганцхан хүчтэй нууц үг цээжлэхэд хангалттай болно.

Хоёр шатлалт баталгаажуулалт

Хоёр шатлалт баталгаажуулалт (2FA) нь нууц үгнээс (“таны мэддэг зүйл”) гадна 2FA төхөөрөмж (жишээ нь YubiKey, “таны эзэмшиж буй зүйл”) ашиглагддаг бөгөөд энэ нь нууц үгээ алдах болон фишингийн (phishing) халдлагаас хамгаалахад тусалдаг.

Дискийг бүрэн шифрлэх

Нөүтбүүкнийхээ дискийг бүхэлд нь шифрлэх нь таны компьютер хулгайд алдагдсан тохиолдолд өгөгдлөө хамгаалах хамгийн хялбар арга юм. Та Linux дээр cryptsetup + LUKS, Windows дээр BitLocker, эсвэл macOS дээр FileVault ашиглаж болно. Энэ нь дискийг бүхэлд нь нууц үгээр (passphrase) хамгаалагдсан түлхүүр бүхий симметрик шифр ашиглан шифрлэдэг.

Хувийн зурвас илгээх

Signal эсвэл Keybase ашиглаарай. Төгсгөлөөс төгсгөлд (End-to-end) хамгаалагдсан аюулгүй байдал нь асимметрик шифрлэлт дээр суурилдаг. Хэрэглэгчийнхээ нийтийн түлхүүрийг найдвартай авах нь энд хамгийн чухал алхам юм. Хэрэв та маш сайн хамгаалалт хүсэж байвал нийтийн түлхүүрүүдийг өөр сувгаар (out-of-band) тулгах (Signal болон Keybase дээр) эсвэл нийгмийн баталгаанд (Keybase дээр) итгэх шаардлагатай.

SSH

Бид өмнөх командын мөрний хичээлээр SSH болон SSH түлхүүр ашиглах талаар үзсэн. Одоо үүний криптограф талыг нь харцгаая.

Та ssh-keygen ажиллуулах үед энэ нь асимметрик түлхүүрийн хослол болох public_key, private_key-ийг үүсгэдэг. Энэ нь үйлдлийн системийн өгдөг энтропийг (техник хангамжийн үйл явдлуудаас цуглуулсан санамсаргүй байдал) ашиглан санамсаргүйгээр үүсгэгддэг. Нийтийн түлхүүр нь яг тэр чигээрээ хадгалагддаг (нийтийнх тул нууцлах шаардлагагүй), харин хувийн түлхүүр нь диск дээр шифрлэгдэж хадгалагдах ёстой. ssh-keygen программ нь хэрэглэгчээс passphrase асуудаг бөгөөд үүнийг KDF-ээр дамжуулан түлхүүр болгон хувиргаж, түүгээрээ хувийн түлхүүрийг симметрик шифр ашиглан шифрлэж хадгалдаг.

Хэрэглэгчийн нийтийн түлхүүр серверийн .ssh/authorized_keys файл дотор хадгалагдсаны дараа, холбогдож буй хэрэглэгч асимметрик гарын үсэг ашиглан өөрийн хэн болохыг баталж чадна. Энэ нь сорилт-хариулт (challenge-response) механизмаар хийгддэг. Ерөнхий түвшинд, сервер санамсаргүй тоо үүсгээд үүнийг клиент рүү илгээнэ. Клиент уг тоон дээр өөрийн хувийн түлхүүрээр гарын үсэг зураад сервер рүү буцааж илгээх бөгөөд сервер нь уг гарын үсгийг өөрт байгаа нийтийн түлхүүрээр баталгаажуулна. Энэ нь клиент серверийн .ssh/authorized_keys файлд байгаа нийтийн түлхүүрт харгалзах хувийн түлхүүрийг эзэмшиж байгааг батлах бөгөөд сервер нэвтрэхийг зөвшөөрнө.

Нөөц эх сурвалжууд

Дасгалууд

  1. Энтропи.
    1. Нууц үгийг бага үсгээр бичигдсэн дөрвөн толь бичгийн үгийн холбоос байхаар сонгосон гэж үзье. Толь бичиг нь 100,000 үгтэй бөгөөд үг бүрийг ижил магадлалтайгаар санамсаргүй сонгоно. Жишээ нь: correcthorsebatterystaple. Энэ нууц үг хэдэн битийн энтропитой вэ?
    2. Өөр нэг хувилбараар 8 тэмдэгттэй санамсаргүй үсэг тоо (жижиг, том үсэг болон тоо орсон) хосолсон нууц үг сонгосон гэж үзье. Жишээ нь: rg8Ql34g. Энэ нууц үг хэдэн битийн энтропитой вэ?
    3. Аль нь илүү хүчтэй нууц үг вэ?
    4. Халдагч секундэд 10,000 нууц үг тааж туршиж чаддаг гэж үзье. Дунджаар нууц үг бүрийг олоход хэр хугацаа зарцуулах вэ?
  2. Криптограф хэш функцүүд. Debian үйлдлийн системийн дүрсийг аль нэг толин тусгал серверээс татаж аваарай (жишээлбэл, энэ Аргентины толин тусгал серверээс). Татаж авсан файлынхаа хэшийг тооцоолж (жишээ нь sha256sum тушаалаар), албан ёсны Debian сайтаас авсан хэштэй тулган шалгана уу (жишээ нь debian.org дээр байрлуулсан энэ файл).
  3. Симметрик криптограф. OpenSSL ашиглан файлыг AES шифрлэлтээр шифрлээрэй: openssl aes-256-cbc -salt -in {оролтын файл} -out {гаралтын файл}. Файлын агуулгыг cat эсвэл hexdump ашиглан хараарай. Дараа нь openssl aes-256-cbc -d -in {оролтын файл} -out {гаралтын файл} тушаалаар буцааж тайлаад, файл хэвээрээ байгаа эсэхийг cmp тушаалаар шалгаарай.
  4. Асимметрик криптограф.
    1. Өөрийн хандах эрхтэй компьютер дээр SSH түлхүүрүүд үүсгээрэй (Athena-г ашиглаж болохгүй, учир нь Kerberos нь SSH түлхүүртэй хачирхалтай байдлаар ажилладаг). Таны хувийн түлхүүр passphrase-ээр хамгаалагдсан, хадгалах үед шифрлэгдсэн эсэхийг баталгаажуулаарай.
    2. GPG тохируулаарай.
    3. Anish рүү шифрлэсэн и-мэйл илгээгээрэй (нийтийн түлхүүр).
    4. Git commit дээр git commit -S ашиглан гарын үсэг зурж эсвэл git tag -s ашиглан гарын үсэгтэй tag үүсгээрэй. Commit-ийн гарын үсгийг git show --show-signature тушаалаар, tag-ийн гарын үсгийг git tag -v тушаалаар тус тус баталгаажуулж шалгаарай.

Энэ хуудсыг засварлах.

Лиценз: CC BY-NC-SA.