Google प्रमाणक एक सार्वजनिक सेवा के रूप में उपलब्ध है?


जवाबों:


121

परियोजना खुला स्रोत है। मैंने इसका उपयोग नहीं किया है। लेकिन यह एक प्रलेखित एल्गोरिथ्म (ओपन सोर्स प्रोजेक्ट पेज पर सूचीबद्ध RFC में उल्लिखित) का उपयोग कर रहा है, और प्रमाणक कार्यान्वयन कई खातों का समर्थन करता है।

वास्तविक प्रक्रिया सीधी है। एक बार कोड, अनिवार्य रूप से, एक छद्म यादृच्छिक संख्या जनरेटर है। एक यादृच्छिक संख्या जनरेटर एक सूत्र है जो एक बार एक बीज दिया जाता है, या प्रारंभिक संख्या, यादृच्छिक संख्याओं की एक धारा बनाना जारी रखता है। एक बीज को देखते हुए, जबकि संख्याएं एक दूसरे के लिए यादृच्छिक हो सकती हैं, अनुक्रम स्वयं नियतात्मक है। इसलिए, जब आपके पास आपका डिवाइस और सर्वर "सिंक में" होता है, तो डिवाइस जो रैंडम नंबर बनाता है, हर बार जब आप "अगला नंबर बटन" मारते हैं, तो वही होगा, जो रैंडम नंबर सर्वर से उम्मीद करता है।

एक सुरक्षित वन टाइम पासवर्ड सिस्टम एक यादृच्छिक संख्या जनरेटर की तुलना में अधिक परिष्कृत है, लेकिन अवधारणा समान है। डिवाइस और सर्वर को सिंक में रखने में मदद करने के लिए अन्य विवरण भी हैं।

इसलिए, प्रमाणीकरण की मेजबानी के लिए किसी और की आवश्यकता नहीं है, जैसे, OAuth कहते हैं। इसके बजाय आपको उस एल्गोरिथ्म को लागू करने की आवश्यकता है जो उन एप्लिकेशन के अनुकूल है जो Google मोबाइल उपकरणों के लिए प्रदान करता है। वह सॉफ्टवेयर ओपन सोर्स प्रोजेक्ट पर उपलब्ध (होना चाहिए) है।

आपके परिष्कार के आधार पर, आपके पास इस प्रक्रिया के सर्वर पक्ष को लागू करने के लिए ओएसएस परियोजना और आरएफसी देने की आवश्यकता है। मुझे नहीं पता कि आपके सर्वर सॉफ़्टवेयर (PHP, Java, .NET, आदि) के लिए कोई विशिष्ट कार्यान्वयन है या नहीं

लेकिन, विशेष रूप से, आपको इसे संभालने के लिए ऑफसाइट सेवा की आवश्यकता नहीं है।


3
दूसरी ओर, पहले से मौजूद, अच्छी तरह से ज्ञात, कई अलग-अलग मोबाइल उपकरणों पर उपलब्ध समाधान प्राप्त करने के लिए आसान उपयोग करने से बहुत लाभ होता है ... (संकेत संकेत)
सरल

26
आप एसएमएस का मतलब? यह धीमा, अविश्वसनीय और महंगा है।
अचराफ अल्मोउलौडी

मैं कैसे शुद्ध जावा में वेबसाइटों के लिए Google प्रमाणक / RFC6238 संगत 2FA को लागू करने के बारे में भी ब्लॉग: asaph.org/2016/04/google-authenticator-2fa-java.html (बेशर्म प्लग)
असफ़

2
FYI NIST अगस्त 2016 तक एसएमएस का उपयोग करते हुए टू-फैक्टर ऑथेंटिकेशन की सिफारिश करने वाला कोई लंबा नहीं है। इसकी असुरक्षित माना जाने वाली लागत को कभी नहीं।
ThePQQ

57

एल्गोरिथ्म RFC6238 में प्रलेखित है । थोड़ा इस तरह से जाता है:

  • आपका सर्वर उपयोगकर्ता को Google प्रमाणक में स्थापित करने के लिए एक रहस्य देता है। Google ऐसा क्यूआर कोड के रूप में प्रलेखित करता है
  • Google प्रमाणक यूनिक्स समय के SHA1-HMAC और गुप्त (RFC में इस पर और अधिक विवरण) से 6 अंकों का कोड बनाता है
  • सर्वर 6-अंकीय कोड को सत्यापित करने के लिए गुप्त / यूनिक्स समय भी जानता है।

मैंने यहाँ जावास्क्रिप्ट में एल्गोरिथ्म को लागू करने वाला एक नाटक किया है: http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/


20

PHP के लिए विभिन्न प्रकार के पुस्तकालय हैं (द लैंप स्टैक)

पीएचपी

https://code.google.com/p/ga4php/

http://www.idontplaydarts.com/2011/07/google-totp-two-factor-authentication-for-php/

टू-फैक्टर कॉरपोरेशन को लागू करते समय आपको सावधान रहना चाहिए, आपको सर्वर पर अपनी घड़ियों को सुनिश्चित करने की आवश्यकता है और क्लाइंट को सिंक्रनाइज़ किया जाता है, ताकि टोकन पर ब्रूट-फोर्स के हमलों के खिलाफ सुरक्षा हो और जो शुरुआती बीज का उपयोग किया जाता है वह काफी बड़ा हो।


सामग्री बहुत अच्छी थी, लेकिन पहले लिंक का उपयोग करने वाले किसी को भी SQL इंजेक्शन रोकथाम विधियों को लागू करना चाहिए, क्योंकि कुछ संभावित खामियां हैं। पहले एक के लिए उठाए गए मुद्दों को देखें। दूसरा लिंक एकदम सही है।
सेप्ट्रोनिक

9

आप मेरे प्रश्न के उत्तर के रूप में पोस्ट किए गए मेरे समाधान का उपयोग कर सकते हैं ( पूर्ण पायथन कोड और स्पष्टीकरण है ):

पायथन में Google प्रमाणक कार्यान्वयन

मुझे लगता है कि PHP या पर्ल में इसे लागू करना आसान है। यदि आपको इससे कोई समस्या है, तो कृपया मुझे बताएं।

मैंने गीथ पर अपना कोड पायथन मॉड्यूल के रूप में भी पोस्ट किया है


1
इस तथ्य के थोड़ी देर बाद ... मैं सिर्फ यह उल्लेख करके पालन करना चाहता था कि CPAN पर एक पर्ल मॉड्यूल है: प्रामाणिक :: GoogleAuthenticator ( search.cpan.org/dist/Auth-GoogleAuthenticator )।
डेविड

6

मुझे यह मिला: https://github.com/PHPGangsta/GoogleAuthenticator । मैंने इसका परीक्षण किया और मेरे लिए ठीक काम करता है।


1
मुझे लगता है कि आप github.com/RobThree/TwoFactorAuth पसंद करेंगे । यह उपरोक्त पुस्तकालय पर आधारित है, लेकिन अधिक सुविधाओं और स्पष्ट प्रलेखन के साथ इस पर एक बड़ा सुधार है।
Ema4rl


3

हां, किसी नेटवर्क सेवा की आवश्यकता नहीं है, क्योंकि Google प्रमाणक ऐप Google सर्वर के साथ संचार नहीं करेगा, यह सिर्फ उस initital रहस्य के साथ समन्वयित रखता है जो समय बीतने के दौरान आपका सर्वर जनरेट करता है (क्यूआर कोड से आपके फोन में इनपुट)।


2

LAMP नहीं, लेकिन यदि आप C # का उपयोग करते हैं तो यह मेरे द्वारा उपयोग किया जाने वाला कोड है:

मूल रूप से कोड:

https://github.com/kspearrin/Otp.NET

Base32Encoding वर्ग इस उत्तर से है:

https://stackoverflow.com/a/7135008/3850405

उदाहरण कार्यक्रम:

class Program
{
    static void Main(string[] args)
    {
        var bytes = Base32Encoding.ToBytes("JBSWY3DPEHPK3PXP");

        var totp = new Totp(bytes);

        var result = totp.ComputeTotp();
        var remainingTime = totp.RemainingSeconds();
    }
}

TOTP:

public class Totp
{
    const long unixEpochTicks = 621355968000000000L;

    const long ticksToSeconds = 10000000L;

    private const int step = 30;

    private const int totpSize = 6;

    private byte[] key;

    public Totp(byte[] secretKey)
    {
        key = secretKey;
    }

    public string ComputeTotp()
    {
        var window = CalculateTimeStepFromTimestamp(DateTime.UtcNow);

        var data = GetBigEndianBytes(window);

        var hmac = new HMACSHA1();
        hmac.Key = key;
        var hmacComputedHash = hmac.ComputeHash(data);

        int offset = hmacComputedHash[hmacComputedHash.Length - 1] & 0x0F;
        var otp = (hmacComputedHash[offset] & 0x7f) << 24
               | (hmacComputedHash[offset + 1] & 0xff) << 16
               | (hmacComputedHash[offset + 2] & 0xff) << 8
               | (hmacComputedHash[offset + 3] & 0xff) % 1000000;

        var result = Digits(otp, totpSize);

        return result;
    }

    public int RemainingSeconds()
    {
        return step - (int)(((DateTime.UtcNow.Ticks - unixEpochTicks) / ticksToSeconds) % step);
    }

    private byte[] GetBigEndianBytes(long input)
    {
        // Since .net uses little endian numbers, we need to reverse the byte order to get big endian.
        var data = BitConverter.GetBytes(input);
        Array.Reverse(data);
        return data;
    }

    private long CalculateTimeStepFromTimestamp(DateTime timestamp)
    {
        var unixTimestamp = (timestamp.Ticks - unixEpochTicks) / ticksToSeconds;
        var window = unixTimestamp / (long)step;
        return window;
    }

    private string Digits(long input, int digitCount)
    {
        var truncatedValue = ((int)input % (int)Math.Pow(10, digitCount));
        return truncatedValue.ToString().PadLeft(digitCount, '0');
    }

}

Base32Encoding:

public static class Base32Encoding
{
    public static byte[] ToBytes(string input)
    {
        if (string.IsNullOrEmpty(input))
        {
            throw new ArgumentNullException("input");
        }

        input = input.TrimEnd('='); //remove padding characters
        int byteCount = input.Length * 5 / 8; //this must be TRUNCATED
        byte[] returnArray = new byte[byteCount];

        byte curByte = 0, bitsRemaining = 8;
        int mask = 0, arrayIndex = 0;

        foreach (char c in input)
        {
            int cValue = CharToValue(c);

            if (bitsRemaining > 5)
            {
                mask = cValue << (bitsRemaining - 5);
                curByte = (byte)(curByte | mask);
                bitsRemaining -= 5;
            }
            else
            {
                mask = cValue >> (5 - bitsRemaining);
                curByte = (byte)(curByte | mask);
                returnArray[arrayIndex++] = curByte;
                curByte = (byte)(cValue << (3 + bitsRemaining));
                bitsRemaining += 3;
            }
        }

        //if we didn't end with a full byte
        if (arrayIndex != byteCount)
        {
            returnArray[arrayIndex] = curByte;
        }

        return returnArray;
    }

    public static string ToString(byte[] input)
    {
        if (input == null || input.Length == 0)
        {
            throw new ArgumentNullException("input");
        }

        int charCount = (int)Math.Ceiling(input.Length / 5d) * 8;
        char[] returnArray = new char[charCount];

        byte nextChar = 0, bitsRemaining = 5;
        int arrayIndex = 0;

        foreach (byte b in input)
        {
            nextChar = (byte)(nextChar | (b >> (8 - bitsRemaining)));
            returnArray[arrayIndex++] = ValueToChar(nextChar);

            if (bitsRemaining < 4)
            {
                nextChar = (byte)((b >> (3 - bitsRemaining)) & 31);
                returnArray[arrayIndex++] = ValueToChar(nextChar);
                bitsRemaining += 5;
            }

            bitsRemaining -= 3;
            nextChar = (byte)((b << bitsRemaining) & 31);
        }

        //if we didn't end with a full char
        if (arrayIndex != charCount)
        {
            returnArray[arrayIndex++] = ValueToChar(nextChar);
            while (arrayIndex != charCount) returnArray[arrayIndex++] = '='; //padding
        }

        return new string(returnArray);
    }

    private static int CharToValue(char c)
    {
        int value = (int)c;

        //65-90 == uppercase letters
        if (value < 91 && value > 64)
        {
            return value - 65;
        }
        //50-55 == numbers 2-7
        if (value < 56 && value > 49)
        {
            return value - 24;
        }
        //97-122 == lowercase letters
        if (value < 123 && value > 96)
        {
            return value - 97;
        }

        throw new ArgumentException("Character is not a Base32 character.", "c");
    }

    private static char ValueToChar(byte b)
    {
        if (b < 26)
        {
            return (char)(b + 65);
        }

        if (b < 32)
        {
            return (char)(b + 24);
        }

        throw new ArgumentException("Byte is not a value Base32 value.", "b");
    }

}


-1

C # उपयोगकर्ता के लिए, एक बार टोकन कोड को सत्यापित करने के तरीके को समझने के लिए इस सरल कंसोल ऐप को चलाएं। ध्यान दें कि हमें पहले Nuget पैकेज से लाइब्रेरी Otp.Net स्थापित करने की आवश्यकता है ।

static string secretKey = "JBSWY3DPEHPK3PXP"; //add this key to your Google Authenticator app  

private static void Main(string[] args)
{
        var bytes = Base32Encoding.ToBytes(secretKey);

        var totp = new Totp(bytes);

        while (true)
        {
            Console.Write("Enter your code from Google Authenticator app: ");
            string userCode = Console.ReadLine();

            //Generate one time token code
            string tokenInApp = totp.ComputeTotp();
            int remainingSeconds = totp.RemainingSeconds();

            if (userCode.Equals(tokenInApp)
                && remainingSeconds > 0)
            {
                Console.WriteLine("Success!");
            }
            else
            {
                Console.WriteLine("Failed. Try again!");
            }
        }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.