• Hi I am trying to generate time based single sign on tokens on my Pixl and puckjs. these can then be sent to a PC or phone over BT via the keyboard HID.

    My research so far says that I need the crypto.js lib from modules and OTPAuth from npm as it has no dependencies

    So far I am only getting erros. I think I do not have my requires working I will post more after I get better results

  • I think I have found the issue the OTPAuth is too large when loaded with the crypto.js lib.

    var crypto = require("crypto");
    var otp = require("https://raw.githubusercontent.c­om/hectorm/otpauth/master/dist/otpauth.m­in.js");
    
    

    Gives the following error

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     2v03 (c) 2018 G.Williams
    >Uncaught SyntaxError: Got UNFINISHED STRING expected EOF
     at line 1 col 98
    ...aster/dist/otpauth.min.js","(function­(){/*\n otpauth v4.0.0 ...
                                  ^
    Execution Interrupted
    New interpreter error: LOW_MEMORY,MEMORY
    >Uncaught Error: Module https://raw.githubusercontent.com/hector­m/otpauth/master/dist/otpauth.min.js not found
     at line 3 col 81
    ...master/dist/otpauth.min.js");
                                  ^
    > 
    

    I will look for a different OTP lib

  • I am now trying Tiny-OTP which is only 4K when minified. I still get a memory error

    1. https://github.com/triestpa/Tiny-OTP
  • Now trying JS-OTP but still rungging low on memory...

    https://github.com/jiangts/JS-OTP

  • Sat 2019.08.10

    Hello @user101436, while I'm not going to be able to find a solution to the issue you have, as the crypto and OAuth topics are beyond my knowledge base, I can confirm that attempting to load just the otp file on to an MDBT42Q, produces the same error.

    >process.memory()
    ={ "free": 2476, "usage": 24, "total": 2500, "history": 7,
    

    I don't have a Puck nor a Pixl handy, but I believe the Pixl has the same memory capacity. Would you mind posting process.memory() for others to assist please.

    I double checked with Google's Closure Compiler and there don't appear to be obvious code/string related errors.

    I saved the .min.js file to disk on Windows10 and have a file size of 25K. I was able to load a 29K file onto the MDBT board, but my file has comment blocks that are stripped prior to upload.

    Are you able to pare down that file?

    ' at line 1 col 98 ...aster/dist/otpauth.min.js","'

    Do you know if this otp module can even be loaded on to an Espruino device?
    It is quite possible that the length of that particular minified string is just too long for the receive buffer on Espruino.

    '){return"undefined"!=typeof window&&window===f?'

    Around the fifth line down scares me a bit. If this is the browser window object, this file may eventually load, but possibly not execute on an Espruino device.

  • New interpreter error: LOW_MEMORY,MEMORY

    The LOW_MEMORY means the Espruino is low on memory, but it's just a warning, if you see it alone.
    MEMORY means Espruino definitely ran out of memory.

    You can try one thing: In the Web IDE settings, go to Communication, and

    • check "Modules uploaded as functions"
    • Save on Send -> set to "Direct to Flash"

    Btw https://github.com/triestpa/Tiny-OTP fits this way, but there is an error running it:

    Uncaught SyntaxError: Got '=' expected ','
     at line 1 col 69
    ...ports=class{constructor(a,b='utf8'){'­base32'===b&&(a=e.decod...
                                  ^
    

    I think Espruino doesn't support default parameters.

    As Robin said, there could be couple of tiny issues preventing you from uploading code that runs fine on node or in browser...

  • Sat 2019.08.10

    'I think Espruino doesn't support default parameters'

    Bingo! @AkosLukacs you are correct. Not implemented yet. Below ES6 heading:

    http://www.espruino.com/Features

  • Thanks for the suggestions I have JS-OTP (One Time Password) loading now without the error or memory warning by editing out the ES6 default values. I cut and pasted the GIT hub code into the right hand IDE panel and uploaded it from there. I also removed any browser objects as the code was designed to work in browser.

    But I hit a new issue with HMAC. (HMAC stands for Keyed-Hashing for Message Authentication) The hash features used by JS-OTP and TinyOTP expect a .hmac method on the hash object. The built in crypto libs do not have this feature.

    I don't think I can implement HMAC so I am looking for an OTP implementation that is not using HMAC.

    I will update here when I make progress.

  • @user101436 Did you do any progress? I'm struggeling with the same issue. I would really love to secure some stuff via TOTP. You know there's the crypto module and the hmac module but there is no tutorial to use them correctly or to create TOTPs.. There is just an outdated tutorial on https://www.espruino.com/hmac because they removed the hashlib with version 2v00 (see changelog https://www.espruino.com/ChangeLog).

  • Hello,

    I've just gone down a rabbit hole trying to discover how best to do this, and have written some Python code that seems to work. I think it should be OK to translate this into Javascript.

    I found a Javascript SHA1 implementation that works in the Espruino simulator at http://webtoolkit.info/javascript_sha1.h­tml

    I had some Python code to do TOTP tokens so had a go at rewriting it to use my own HMAC algorithm based on the Wikipedia page https://en.wikipedia.org/wiki/Hash-based­_message_authentication_code

    I think the Javascript code above returns the digest as hex - it will need to be changed to return an array of bytes but I haven't looked how to do that. But once that is done, I think my python call to sha1() can just use the Javascript code.

    The "get_hotp_token" function was the original one - I forget where it came from. From what I can see my function and this function return the same results.

    I hope it should be OK to transliterate my Python code into Javascript. The 'chr' and 'ord' function should be removed - this is as the code uses Python strings, but Javascript arrays won't have this problem. Likewise, the 'b'\x00' *' part is a Python thing that would need to be rewritten for Javascript.

    I hope my code when combined with the Javascript SHA1 code gives some help anyway.

    # SHA1 block size = 512 bits, or 64 bytes
    # https://en.wikipedia.org/wiki/Hash-based­_message_authentication_code
    
    def colin_hmac(key,msg):
        # https://en.wikipedia.org/wiki/Hash-based­_message_authentication_code
        # https://raw.githubusercontent.com/python­/cpython/master/Lib/hmac.py
        # key is 10 bytes, msg is 8 bytes
        # Pad key to be 64 bytes long
        blocksize = 64
        key = key + b'\x00' * (blocksize - len(key)) # Pad key with 0 byte values
        # Build up new strings with the key XORed with 0x36 and 0x5C
        k36=""
        k5c=""
        for c in key:
            k36 = k36+chr(ord(c) ^ 0x36)
            k5c = k5c+chr(ord(c) ^ 0x5c)
            
        hmac=sha1(k5c + sha1(k36 + msg).digest())
        return hmac.digest()
    
    def colin_hotp_token(secret, intervals_no):
        # Key is a 10 byte array
        key = base64.b32decode(secret, True)
        # Python debug : print the key as bytes
        [#print](http://forum.espruino.com/searc­h/?q=%23print) "KEY",[ord(x) for x in key]
        [#keybytes](http://forum.espruino.com/se­arch/?q=%23keybytes)=[0, 68, 50, 20, 199, 66, 64, 17, 12, 133]
        # msg is 8 bytes long - number with last byte = least significant
        msg = struct.pack(">Q", intervals_no)
        [#msgbytes](http://forum.espruino.com/se­arch/?q=%23msgbytes)=[0, 0, 0, 0, 0, 0, 0, 1]
    
        colin_hm=colin_hmac(key,msg)
        binary=offset=ord(colin_hm[19]) & 0x0f
        binary=((ord(colin_hm[offset]) & 0x7f) << 24) | ((ord(colin_hm[offset+1]) & 0xff) << 16) | ((ord(colin_hm[offset+2]) & 0xff) << 8 ) | (ord(colin_hm[offset+3]) & 0xff)
        # We want the last 6 digits
        return binary % 1000000
        
    def get_hotp_token(secret, intervals_no):
        key = base64.b32decode(secret, True)
        msg = struct.pack(">Q", intervals_no)
        hm = hmac.new(key, msg, hashlib.sha1)
        h = hm.digest() # Return byte array
        o = ord(h[19]) & 0x0f
        h = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000   
        return h
    
    
  • Hmm. The posting above went a bit wrong - I guess I'm posting Python code rather than Javascript.

    Here is the garbled bit, not marked as code to hopefully keep the forum happy

    def colin_hotp_token(secret, intervals_no):
    # Key is a 10 byte array
    key = base64.b32decode(secret, True)
    # Python debug : print the key as bytes
    #print "KEY",[ord(x) for x in key]

    #keybytes=[0, 68, 50, 20, 199, 66, 64, 17, 12, 133]
    # msg is 8 bytes long - number with last byte = least significant
    msg = struct.pack(">Q", intervals_no)
    #msgbytes=[0, 0, 0, 0, 0, 0, 0, 1]

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Sending single sign in tokens using Keybaord HID for TOTP sign in

Posted by Avatar for user101436 @user101436

Actions