Connect/Login using TOTP


  • I am struggling with the new TOTP ...unable to connect. Can someone help with basic code ?

    SmartApi connect = new SmartApi(api_key, JWTToken, RefreshToken);
    
               OutputBaseClass obj = new OutputBaseClass();
    
               //Login by client code and password......... old code
               obj = connect.GenerateSession(Client_code, Password);
               //Login by client code and password .....new code ?? how
               //obj = connect.GenerateSession(Client_code, Password, totp);
    

    how to get the totp and pass it to GenerateSession ?


  • @amrutjk

    Hi,
    Was your login issue resolved?
    Thanks



  • @srikanth-yarra

    		string Client_code = "MY_CLIENT_CODE"; 
    		string MPIN = "MY_MPIN"; 
    		string Password = "MY_PASSWORD"; 
    		string api_key = "MY_API_KEY"; 
    
    		SmartApi connect = new SmartApi(api_key, JWTToken, RefreshToken);
    
    		OutputBaseClass obj = new OutputBaseClass();
    
    		obj = connect.GenerateSession(Client_code, MPIN);
    

    I am getting I am getting an error "Invalid totp"

    How to fix this>>>


  • @amrutjk
    from pyotp import TOTP
    totp=TOTP(totp_code).now()
    // totp_code from authenticator app.
    obj=SmartConnect(api_key=api_key)
    data=obj.generateSession(client_code, mpin, totp)


  • @amrutjk public class Totp : Otp
    {
    private const long unixEpochTicks = 621355968000000000L;

        private const long ticksToSeconds = 10000000L;
    
        private readonly int step;
        private readonly int totpSize;
        private readonly TimeCorrection correctedTime;
    
        public Totp(byte[] secretKey, int step = 30, OtpHashMode mode = OtpHashMode.Sha1, int totpSize = 6, TimeCorrection timeCorrection = null)
            : base(secretKey, mode)
        {
            VerifyParameters(step, totpSize);
    
            this.step = step;
            this.totpSize = totpSize;
    
            // we never null check the corrected time object.  Since it's readonly, we'll ensure that it isn't null here and provide neatral functionality in this case.
            correctedTime = timeCorrection ?? TimeCorrection.UncorrectedInstance;
        }
    
        public Totp(IKeyProvider key, int step = 30, OtpHashMode mode = OtpHashMode.Sha1, int totpSize = 6, TimeCorrection timeCorrection = null)
            : base(key, mode)
        {
            VerifyParameters(step, totpSize);
    
            this.step = step;
            this.totpSize = totpSize;
    
            // we never null check the corrected time object.  Since it's readonly, we'll ensure that it isn't null here and provide neatral functionality in this case.
            correctedTime = timeCorrection ?? TimeCorrection.UncorrectedInstance;
        }
    
        private static void VerifyParameters(int step, int totpSize)
        {
            if (!(step > 0))
            {
                throw new ArgumentOutOfRangeException(nameof(step));
            }
    
            if (!(totpSize > 0))
            {
                throw new ArgumentOutOfRangeException(nameof(totpSize));
            }
    
            if (!(totpSize <= 10))
            {
                throw new ArgumentOutOfRangeException(nameof(totpSize));
            }
        }
    
        public string ComputeTotp(DateTime timestamp)
        {
            return ComputeTotpFromSpecificTime(correctedTime.GetCorrectedTime(timestamp));
        }
    
        public string ComputeTotp()
        {
            return ComputeTotpFromSpecificTime(correctedTime.CorrectedUtcNow);
        }
    
        private string ComputeTotpFromSpecificTime(DateTime timestamp)
        {
            long window = CalculateTimeStepFromTimestamp(timestamp);
            return Compute(window, hashMode);
        }
    
        public bool VerifyTotp(string totp, out long timeStepMatched, VerificationWindow window = null)
        {
            return VerifyTotpForSpecificTime(correctedTime.CorrectedUtcNow, totp, window, out timeStepMatched);
        }
    
        public bool VerifyTotp(DateTime timestamp, string totp, out long timeStepMatched, VerificationWindow window = null)
        {
            return VerifyTotpForSpecificTime(correctedTime.GetCorrectedTime(timestamp), totp, window, out timeStepMatched);
        }
    
        private bool VerifyTotpForSpecificTime(DateTime timestamp, string totp, VerificationWindow window, out long timeStepMatched)
        {
            long initialStep = CalculateTimeStepFromTimestamp(timestamp);
            return Verify(initialStep, totp, out timeStepMatched, window);
        }
    
        private long CalculateTimeStepFromTimestamp(DateTime timestamp)
        {
            long unixTimestamp = (timestamp.Ticks - unixEpochTicks) / ticksToSeconds;
            long window = unixTimestamp / step;
            return window;
        }
    
        public int RemainingSeconds()
        {
            return RemainingSecondsForSpecificTime(correctedTime.CorrectedUtcNow);
        }
    
        public int RemainingSeconds(DateTime timestamp)
        {
            return RemainingSecondsForSpecificTime(correctedTime.GetCorrectedTime(timestamp));
        }
    
        private int RemainingSecondsForSpecificTime(DateTime timestamp)
        {
            return step - (int)(((timestamp.Ticks - unixEpochTicks) / ticksToSeconds) % step);
        }
    
        protected override string Compute(long counter, OtpHashMode mode)
        {
            byte[] data = KeyUtilities.GetBigEndianBytes(counter);
            long otp = CalculateOtp(data, mode);
            return Digits(otp, totpSize);
        }
    }

  • @amrutjk

    public static string GetTOTP(string secretKey, int step = 30, OtpHashMode mode = OtpHashMode.Sha1, int length = 6)
    {
    Totp otpCalc = new(Base32Encoding.ToBytes(secretKey), step, mode, length);
    int rmngTime = otpCalc.RemainingSeconds() - 1;
    if (rmngTime < 5)
    {
    Thread.Sleep(rmngTime * 1000);
    }
    return otpCalc.ComputeTotp();
    }