परिचय: "खुद का बनाया हुआ" प्रमाणीकरण जोखिम क्यों है?
\n\nकल्पना करें: आप Kotlin में एक एप्लिकेशन लिख रहे हैं - चाहे वह Android क्लाइंट हो या Ktor/Spring Boot पर बैकएंड। आप जल्दी से एक लॉगिन फॉर्म बनाते हैं, पासवर्ड SharedPreferences में सेव करते हैं और खुश होते हैं कि सब कुछ काम कर रहा है। और एक हफ्ते बाद आपको संदेश मिलता है: "आपका एप्लिकेशन हैक हो गया, डेटा लीक हो गया"। परिचित लगता है? दुर्भाग्य से, यह एक क्लासिक मामला है।
\n\nKotlin में सुरक्षित प्रमाणीकरण केवल "पासवर्ड जांचना" नहीं है। यह एक पूरी पारिस्थितिकी तंत्र है: हैशिंग, टोकन, अनुरोध जालसाजी से सुरक्षा, गुप्त जानकारी का सुरक्षित भंडारण। इस लेख में, हम चर्चा करेंगे कि सामान्य गलतियों से कैसे बचें और एक मजबूत लॉगिन सिस्टम कैसे बनाएं। चलिए शुरू करते हैं!
\n\n1. पासवर्ड हैशिंग: bcrypt और इसके साथी
\n\nसुरक्षा का पहला नियम: पासवर्ड को कभी भी सादे टेक्स्ट में स्टोर न करें। भले ही आप HTTPS का उपयोग कर रहे हों, डेटाबेस से समझौता हो सकता है। आपका काम केवल हैश को स्टोर करना है।
\n\nMD5 और SHA बुरे क्यों हैं?
\nये एल्गोरिदम तेज़ हैं। और तेज़ हैश हैकर के लिए एक सपना हैं: वे प्रति सेकंड अरबों संयोजनों को आज़मा सकते हैं। इसके बजाय, bcrypt, scrypt या Argon2 का उपयोग करें। ये जानबूझकर धीमे हैं और GPU हमलों के प्रति प्रतिरोधी हैं।
\n\njbcrypt लाइब्रेरी का उपयोग करते हुए Kotlin में उदाहरण:
import org.mindrot.jbcrypt.BCrypt\n\nfun hashPassword(password: String): String {\n val salt = BCrypt.gensalt(12) // cost factor 12 — इष्टतम\n return BCrypt.hashpw(password, salt)\n}\n\nfun checkPassword(password: String, hashed: String): Boolean {\n return BCrypt.checkpw(password, hashed)\n}\n\nमहत्वपूर्ण: सॉल्ट स्वचालित रूप से उत्पन्न होता है और हैश में एम्बेड हो जाता है। आपको इसे अलग से स्टोर करने की आवश्यकता नहीं है।
\n\n2. JWT: हल्का और सुरक्षित प्रमाणीकरण
\n\nJSON Web Token (JWT) पक्षों के बीच दावों (claims) को स्थानांतरित करने का एक मानक है। Kotlin में, आप java-jwt (Auth0) या jsonwebtoken (jjwt) लाइब्रेरी का उपयोग कर सकते हैं।
Kotlin पर JWT जनरेशन
\n\nimport io.jsonwebtoken.Jwts\nimport io.jsonwebtoken.SignatureAlgorithm\nimport io.jsonwebtoken.security.Keys\nimport java.util.Date\n\nfun generateToken(userId: String, secretKey: String): String {\n val key = Keys.hmacShaKeyFor(secretKey.toByteArray())\n return Jwts.builder()\n .setSubject(userId)\n .setIssuedAt(Date())\n .setExpiration(Date(System.currentTimeMillis() + 3600_000)) // 1 घंटा\n .signWith(key, SignatureAlgorithm.HS256)\n .compact()\n}\n\nटोकन सत्यापन
\n\nfun validateToken(token: String, secretKey: String): String? {\n return try {\n val key = Keys.hmacShaKeyFor(secretKey.toByteArray())\n val claims = Jwts.parserBuilder()\n .setSigningKey(key)\n .build()\n .parseClaimsJws(token)\n .body\n claims.subject // userId लौटाता है\n } catch (e: Exception) {\n null // टोकन अमान्य या समाप्त हो गया है\n }\n}\n\nसुझाव: गुप्त कुंजी को कोड में स्टोर न करें। पर्यावरण चर या Vault का उपयोग करें।
\n\n3. Android पर टोकन का सुरक्षित भंडारण
\n\nयदि आप Kotlin में मोबाइल एप्लिकेशन लिख रहे हैं, तो एक्सेस टोकन को SharedPreferences में स्टोर नहीं किया जा सकता - यह एक खुली फ़ाइल है जिसे अन्य एप्लिकेशन या रूट एक्सेस वाला हमलावर पढ़ सकता है।
\n\nEncryptedSharedPreferences (AndroidX Security से) या Keystore का उपयोग करें:
\n\nimport androidx.security.crypto.EncryptedSharedPreferences\nimport androidx.security.crypto.MasterKey\n\nfun saveToken(context: Context, token: String) {\n val masterKey = MasterKey.Builder(context)\n .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)\n .build()\n\n val sharedPreferences = EncryptedSharedPreferences.create(\n context,\n "secure_prefs",\n masterKey,\n