get SHA1 hash

Posted on
Page
of 2
/ 2
Next
  • Just playing around a bit with websockets.
    I wonder if there is a way to create a websocket server on Espruino.
    Right now my problem is to calculate SHA1-hash from a given Sec-WebSocket-Key, to initiate a connection between client and server.
    There are some sources available, but it would take away a lot of available memory.

  • There's a bug open for it here - while you could hack something up in JS you'd basically be creating your own web server from scratch.

    It's much better if it's built into the Espruino firmware itself. I pasted some code there that does most of what's needed to enable WebSockets, minus the SHA1.

    However, there's also a branch (AES) on GitHub which contains mbedtls, which contains a SHA1 implementation. At some point I'll expose that and then WebSockets can be enabled easily - but it's probably easiest to wait until that happens.

  • I am actually working on adding it to the ws module, yes it is a 1 big function and still trying to figure out how to save memory.

  • Do you actually need it for on the client side?

  • No, I thought I would extend the ws module and make it cover both the client and server.

    So we can use it like:

    /// Client
    var WebSocket = require("ws");
     var ws = new WebSocket("HOST",{
          port: 8080,
          protocolVersion: 13,
          origin: 'Espruino',
          keepAlive: 60  // Ping Interval in seconds.
        });enter code here
    
    /// Server
    var WebSocketServer = require("ws").Server;
     var wss = new WebSocketServer({port: 8080});
     wss.on('connection', function(ws) {
      ws.on('message', function(message) {
        bla bla
      });
    

    And thats why I wanted a way to only require the sha1 function if I am creating a server but for the client I really don't need it.

  • As I'd said above, it'd be much better if someone could actually just build this into Espruino, in C. It'd be faster and would use much less memory.

    While you can do a server in JS, if you're planning on making it serve up webpages too (which you'll have to if using Pico+ESP8266 because you can only have one webserver at a time), you'd have to implement your own HTTP server in JS and not use Espruino's own one.

  • At the very least I'd create a new module called wsserver or something - so people who just want the client don't have to pull in a SHA1 implementation.

  • yup i guess that will be my only choice, since I am not good in C i am trying my best to implement it with js.

    I guess for now we can have 2 modules ws & wss

  • @sameh.hady, may be we can share our experience. Base is the same, since my knowledge of C is poor. May be waiting for somebody adding a server to Espruino, as suggested by @Gordon, would be a better way. But at least I learned a lot around datahandling with sockets ;-)
    I've found an SHA1 implementation and added it to my testing environment around Espruino on ESP8266. You can find my actual source here:

    • http://jumspruino.jumware.com/sources/ESP8266Test.js, see function startSocket and SHA-functions.
    • http://jumspruino.jumware.com/sources/WebSocket.htm
      This is far away from being perfect, but it includes SHA1 and decoding/encoding for socket frame. Its tested in my environment with firefox and chrome. For connection I use the http-module from Espruino, which makes it easy to handle headers.
      Todo list, please have in mind, very early status:
    • keep connection alive
    • socket frame for data > 200 bytes
    • problem with IE, which sends uppercase chars in upgrade header.
    • testing, testing, testing
    • .....
  • Nice work @JumJum, in my case I've used a longer Sha1 function which I couldn't include in ESP8266 because of its memory limit. So I couldnt test it actually till now.

    For the keep alive all what you need is sending the ping message to the clients on interval and also pong pack if the client sent a ping.

    In my ws client I found that the server was not sending me any pings and thats why I made the client keep the connections alive by sending ping requests to the server and wait for it's pong.

    Is there any difference between net.createServer & http.createServer? I thought it is better to use the net one.

    I will try your code when I am back home and will let you know

  • http.createServer creates an HTTP server, which parses the headers of the HTTP request for you, net.createServer is a plain TCP/IP one.

    To be honest, if @JumJum's code can use the built in HTTP server that's awesome, and I take back everything I said about the JS implementation :) it might actually be the best way to do it if you can use the existing HTTP server with it.

  • @Gordon is right, I used the HTTP server to get headers parsed.
    BTW, is there an easy way to encode/decode socket frames ? Socket itself delivers raw data and I had to seperate the data part oit of it.
    I don't know how node.js handles this, but can imagine that code for this already exists somewhere around http handling. (sorry lack of C-handling, tried to find and failed.
    May be we could have an option to switch on/off decoding/encoding ?
    To be honest, even this short sha1 takes a lot of memory, at least at runtime.
    Had to use some "optimization" to get it running. And it takes some time to calculate.
    Therefore I would prefer to have sha1 in firmware, same way we have sha224 and sha256.
    And if there is a nicer way to do encode64, please give me a hint.

  • Wow, encode64 is impressive! You actually just needed atoa though ;)

  • in websockets you need to convert string to sha1 then to hex then base64 this hex
    I was doing something like:

    function hexEncode(str) {
        var x = [];
        for (var i = 0; i < str.length; i += 2) {
            x.push(String.fromCharCode("0x" + str.substr(i, 2)));
        }
        return btoa(x.join(""));
    }
    
  • Instead of "0x" + str.substr(i, 2), you could try parseInt(str.substr(i, 2),16). Not much difference, but I guess it feels a bit more reliable :)

  • make sense :D everyday learning something new. still the sha1 function is dang big and in both ways will consume lots of memory. Funny part is I had an idea to make an http request from Espruino to a php page to get the encoded string directly. I guess this would consume way less memory :)

  • Had the same idea first.
    But, .... we would need a server for that, which may not be available in my WiFi at home.
    Another point is additional memory consumption during http get, which is a lot.
    At least compared to available memory on ESP8266.
    During testing, I used process.memory().free, to watch this.
    BTW, forgot to mention, uploading my example needs minimizing.

  • Another idea is to do same as what i did in the client, imagine all clients sending same base64 key, in that case the server will always reply with the same accept key, you can statically define that in the header and no need for the sha1 function anymore.

    And we can use custom client that always use the same key in the header, Espruino client

  • How would you set the key in browser ?

  • maybe we can look into the native websocket object for a way to define it, honestly didnt try it out before.

  • Since i found that its not possible to override main WebSocket object, and since there is no way to establish simple tcp connection with html5. Another solution would be using java applet to form the tcp connection and modify its header to form a websocket client with static headers. I think this one would be possible

  • ...The <applet> tag is not supported in HTML5...

    I guess it is a goner...

  • The <applet> tag is not supported in HTML5. Use <embed> or <object> instead.
    

    It is still possible, they can never remove the support for java applets, they just changed the tag

  • Actually I do think this option is the best one so far, I am into doing a POC to see how will it work

  • Cool...embedded objects are better than sepeate to install plug-ins / extension - and they are safe as long as they are signed... I guess that - and the perforance in the early days - made them rarely appear. Since applets have full access to all resources and therefore have to prompt the user for permission, it is still something that meddles with the user's trust.

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

get SHA1 hash

Posted by Avatar for JumJum @JumJum

Actions