# 06. Mobile Security: mTLS, Certificate Pinning va Secure Enclave

Fintech (Payme, Click, Banklar), kriptovalyuta va maxfiy ma'lumotlar bilan ishlovchi ilovalarda oddiy HTTPS ulanish yetarli emas. 
Nima uchun? Chunki har qanday junior xaker ham o'z kompyuteriga **Charles Proxy** yoki **Proxyman** o'rnatib, telefonga o'z Root CA sertifikatini qo'shishi va barcha HTTPS trafikni ochiq ko'rinishda o'qishi (Man-in-the-Middle) mumkin!

Ushbu darsda biz bank darajasidagi himoya arxitekturasini quramiz.

---

## 1. HTTPS Hujumlari va Public Key Pinning

Foydalanuvchi telefoniga zararli VPN yoki Root sertifikat o'rnatilganda, standart `URLSession` soxta serverga ulanishni xavfsiz deb hisoblaydi.

Bunga qarshi **Public Key Pinning (SPKI SHA-256)** ishlatiladi:

```
[Mobil Ilova] 
     |
     v  (TLS Handshake)
[Server Sertifikatini Olish]
     |
     v
[Sertifikatning Public Key Hash ini Hisoblash]
     |
     +---> Biz ilovaga yozgan SHA-256 hesh bilan 100% mosmi?
           ├── HA: Ulanishga ruxsat berilsin.
           └── YO'Q: ALERTA! Hujum bo'ldi! Ulanish darhol uzilsin!
```

---

## 2. Zero-Trust Cho'qqisi: Mutual TLS (mTLS)

Oddiy TLS da faqatgina telefon serverni tekshiradi. Server esa ulanayotgan tomon haqiqiy mobil ilovami yoki Postman/Curl orqali hujum qilayotgan botmi — bilmaydi.

**mTLS (Ikki Tomonlama TLS)** da:
1. Mobil ilova serverning sertifikatini tekshiradi.
2. **Server ham mobil ilovaning sertifikatini tekshiradi!**

```
Client (iOS)                                     Server (Go)
    |                                                |
    | ----- ClientHello ---------------------------> |
    | <---- ServerHello + Server Certificate ------- |
    |                                                |
    | (Server sertifikatini tekshiradi)              |
    |                                                |
    | ----- Client Certificate + ClientKeyExchange ->|
    |                                                |
    |                                                | (Mijoz sertifikatini tekshiradi)
    |                                                | [Sertifikatsiz yoki soxta bo'lsa -> REJECT]
    | <==== Shifrlangan va Ikki Tomonlama Tasdiqlangan Tunnel ====>
```

Agar xaker serverning IP manzilini bilsa ham, unga hatto so'rov yubora olmaydi — TLS darajasidayoq ulanish to'xtatiladi!

---

## 3. Apple Secure Enclave Bilan Ishlash

Hech qachon shaxsiy kalitlarni (Private Key) ilovaning `UserDefaults`, `Keychain` yoki xotirasida ochiq saqlamang.
Apple qurilmalarida maxsus alohida xavfsizlik chipi mavjud — **Secure Enclave**.

```swift
import Foundation
import Security
import CryptoKit

public final class SecureEnclaveSigner {
    public static func generateHardwareKey() throws -> SecureEnclave.P256.Signing.PrivateKey {
        // Kalit bevosita apparat chipida yaratiladi va hech qachon RAM ga chiqmaydi!
        let accessControl = SecAccessControlCreateWithFlags(
            nil,
            kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
            [.privateKeyUsage, .biometryAny], // FaceID / TouchID talab qilinadi
            nil
        )!

        return try SecureEnclave.P256.Signing.PrivateKey(accessControl: accessControl)
    }

    public static func signPayload(privateKey: SecureEnclave.P256.Signing.PrivateKey, data: Data) throws -> Data {
        // Ma'lumot chip ichiga yuboriladi va chip uni imzolab qaytaradi
        let signature = try privateKey.signature(for: data)
        return signature.rawRepresentation
    }
}
```

---

## 4. gRPC Dynamic HMAC Interceptor (Go & Swift)

Har bir gRPC so'roviga xakerlar uni qayta yubora olmasligi (Replay Attack) uchun bir martalik dinamik imzo qo'shamiz:

```swift
import Foundation
import GRPC
import NIO
import CryptoKit

public final class SecurityInterceptor: ClientInterceptor<Any, Any> {
    private let secretKey: SymmetricKey

    public init(apiKey: String) {
        self.secretKey = SymmetricKey(data: Data(apiKey.utf8))
    }

    override public func send(_ part: GRPCClientRequestPart<Any>, promise: EventLoopPromise<Void>?, context: ClientInterceptorContext<Any, Any>) {
        if case var .metadata(headers) = part {
            let timestamp = String(Int(Date().timeIntervalSince1970))
            let nonce = UUID().uuidString
            let signature = HMAC<SHA256>.authenticationCode(
                for: Data("\(timestamp):\(nonce)".utf8),
                using: secretKey
            )

            headers.add(name: "x-timestamp", value: timestamp)
            headers.add(name: "x-nonce", value: nonce)
            headers.add(name: "x-signature", value: Data(signature).base64EncodedString())
            
            context.send(.metadata(headers), promise: promise)
            return
        }
        context.send(part, promise: promise)
    }
}
```

Ushbu arxitektura orqali mobil ilovangiz har qanday tashqi hujumlardan 100% himoyalanadi!
