Search code examples
javaapiautomationone-time-passwordauthy

Get same two-factor code, like I received in my App Authy in JAVA


I want use API of BitSkins.com, but they use two-factor codes through Authy. For request on BitSkins I need API_key and code. By link: https://bitskins.com/api/, maybe wrote about it, but they haven't solution for JAVA.

https://bitskins.com/api/v1/get_account_balance/?api_key=I_KNOW_IT&code=**CODE_IN_PHONE_GENERATE_AUTOMATICALY**

How to receive same code CODE_IN_PHONE_GENERATE_AUTOMATICALY, like I received in my Authy application on my phone?


Solution

  • I was having the same issues as OP. Just Googling stuff for 5 minutes solved that.

    I am using this little API here.

    My implementation might quite a bit different from you as I am doing this as a part of very big project and my company is funding this.


    Spring Implementation

    In our application, the process is automated and we are using Spring Framework. I have created a bean which is nothing but a Thread that runs indefinitely and generates the Authy code (same as shown in the mobile phone).

    import org.apache.log4j.Logger;
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    import com.sarvika.commonslib.util.StringUtil;
    import com.j256.totp.TwoFactorAuthUtil;
    
    public class Authy2FactorThreadBean extends Thread implements ApplicationContextAware {
    
        private static final Logger logger = Logger.getLogger(Authy2FactorThreadBean.class);
    
        private String base32Secret;
        private String keyId;
    
        private String qrCodeImageUrl;
        private String code;
    
        @Override
        public void run() {
            try {
                TwoFactorAuthUtil twoFactorAuthUtil = new TwoFactorAuthUtil();
    
                qrCodeImageUrl = twoFactorAuthUtil.qrImageUrl(keyId, base32Secret);
                code = twoFactorAuthUtil.generateCurrentNumber(base32Secret);
    
                while (true) {
                    code = twoFactorAuthUtil.generateCurrentNumber(base32Secret);
                    Thread.sleep(1000);
                }
            } catch (Exception ex) {
                logger.error(ex.getMessage(), ex);
            }
        }
    
        @Override
        public void setApplicationContext(ApplicationContext context)
                throws BeansException {
    
            if (StringUtil.isEmpty(base32Secret) || StringUtil.isEmpty(keyId)) {
                logger.warn("Base32 Secret or Key ID not provided. 2Factor Codes will not be generated!!!!!");
                return;
            }
    
            logger.info("Starting 2Factor Generation Thread...");
            start();
    
        }   
    
        public String getBase32Secret() {
            return base32Secret;
        }
    
        public void setBase32Secret(String base32Secret) {
            this.base32Secret = base32Secret;
        }
    
        public String getKeyId() {
            return keyId;
        }
    
        public void setKeyId(String keyId) {
            this.keyId = keyId;
        }
    
        public String getQrCodeImageUrl() {
            return qrCodeImageUrl;
        }
    
        public void setQrCodeImageUrl(String qrCodeImageUrl) {
            this.qrCodeImageUrl = qrCodeImageUrl;
        }
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
    }
    

    Then you create a bean like this:

    <bean id="authy2FactorThreadBean" class="Authy2FactorThreadBean">
        <!-- twofactor.secret is the Secret shown by the Bitskins when you are authorizing your phone -->
        <property name="base32Secret" value="${twofactor.secret}"/>
    
        <!-- twofactor.key is the name of the key which can be displayed by the authenticator program -->
        <property name="keyId" value="${twofactor.key}"/>
    </bean>
    

    And pass it around wherever you want the generated two-factor code.


    Non-Spring Implementation

    Please see this little example by the API Author.