{"id":4,"date":"2015-10-05T21:26:09","date_gmt":"2015-10-05T21:26:09","guid":{"rendered":"http:\/\/10.11.12.20\/wordpress\/?p=4"},"modified":"2020-04-07T14:17:31","modified_gmt":"2020-04-07T21:17:31","slug":"yet-another-garage-door-opener","status":"publish","type":"post","link":"https:\/\/www.casler.org\/wordpress\/yet-another-garage-door-opener\/","title":{"rendered":"Yado &#8211; A Secure Door Opener"},"content":{"rendered":"<p>There&#8217;s been many DIY&nbsp;IoT&nbsp;garage door openers but none of them offered the level of security that is required to secure my home. While it&#8217;s true that most are &#8220;good enough&#8221; placed behind a secure Wifi router, that level of security is unacceptable for a device that is on the publicly facing internet. I trust this device enough where the URL is actually publicly accessible. The only real vulnerability would be a Denial of Service attack. There&#8217;s not much that can be done to secure against that on a uC that costs $2 in unit quantities on&nbsp;eBay.<\/p>\n<p>This project is being published&nbsp;not only to enable you to remake this for yourself, but to also share the novel way of securing payloads between devices without the expensive overhead of TLS\/SSL.<\/p>\n<p>While this was made for the ESP8266, the code and required computation would also be easily ported (I performed some proof of concept tests of&nbsp;this) to an 8 bit Atmel uC.<\/p>\n<p>For a full feature set, take a look at at the front page of the <a href=\"https:\/\/github.com\/mc-hamster\/yado\">Yado project on GitHub<\/a>.<\/p>\n<p><a href=\"http:\/\/www.casler.org\/wordpress\/wp-content\/uploads\/2016\/04\/img_6584.jpg\"><img decoding=\"async\" src=\"http:\/\/www.casler.org\/wordpress\/wp-content\/uploads\/2016\/04\/img_6584.jpg\" alt=\"\"><\/a>&nbsp;&nbsp;<\/p>\n<h2>Open Source<\/h2>\n<p>All the files can be downloaded from the <a href=\"https:\/\/github.com\/mc-hamster\/yado\">Yado repository on GitHub<\/a>.<\/p>\n<p>Update 1 (May 8, 2016) &#8211; Source has been revised to support the v2.0.0 Arduino ESP8266 API. Don&#8217;t build with any version of <a href=\"https:\/\/github.com\/esp8266\/Arduino\">Arduino ESP8266 API<\/a> prior to v2.0.0.<\/p>\n<h2>How it works &#8211; Basics<\/h2>\n<p><a href=\"http:\/\/www.casler.org\/wordpress\/wp-content\/uploads\/2015\/10\/Yado-Front-Page.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-149 size-large aligncenter\" src=\"http:\/\/www.casler.org\/wordpress\/wp-content\/uploads\/2015\/10\/Yado-Front-Page-491x213.png\" alt=\"Yado Front Page\" width=\"491\" height=\"213\" srcset=\"https:\/\/www.casler.org\/wordpress\/wp-content\/uploads\/2015\/10\/Yado-Front-Page.png 491w, https:\/\/www.casler.org\/wordpress\/wp-content\/uploads\/2015\/10\/Yado-Front-Page-300x130.png 300w\" sizes=\"auto, (max-width: 491px) 100vw, 491px\" \/><\/a><\/p>\n<p>Built&nbsp;around the ESP8266 at a&nbsp;cost of about $20-$30 to produce&nbsp;in single unit&nbsp;quantities, Yado uses multiple layers of one way SHA1 message digesting to secure the payload being transmitted. At no time is your password sent in clear text. You can also configure multiple passwords through the Admin UI for the people in your household.<\/p>\n<h2>How it works &#8211;&nbsp;Security<\/h2>\n<p>The message exchange methodology implemented is similar to the (yet custom) implementation to what is used by the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Security_Assertion_Markup_Language\">SAML Single Sign On<\/a>&nbsp;&nbsp;Specification. Other than digesting&nbsp;the network payloads, the other form of attack that had to be addressed was that of packet replay attacks specifically around the inability generate cryptography secure&nbsp;&nbsp;random numbers. A&nbsp;solution was&nbsp;implemented which uses the time required to acquire and log into a WiFi AP as part of the seed of a random number generator. This protocol is also resistant to brute force attacks. This is real security!<\/p>\n<h2>How it works &#8211; Psudocode<\/h2>\n<p><b>Client to Server (Initial Request)<\/b><\/p>\n<p><span style=\"font-weight: 400;\">&gt; Get \/<\/span><\/p>\n<p><b>Server<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Timestamp = 999<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Secret = \u201cSecret\u201d<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Password = \u201cletmein\u201d<\/span><\/p>\n<p><span style=\"font-weight: 400;\">preDigest = \u201c999xSecret\u201d<\/span><\/p>\n<p><span style=\"font-weight: 400;\">serverDigest = sha1(\u201c999xSecret\u201d)<\/span><\/p>\n<p><span style=\"font-weight: 400;\"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8a2ca83d614812d6fa9d49650601b143baf8ef66<\/span><\/p>\n<p><b>Server to Client (Response)<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Timestamp = 999<\/span><\/p>\n<p><span style=\"font-weight: 400;\">serverDigest = 8a2ca83d614812d6fa9d49650601b143baf8ef66<\/span><\/p>\n<p><b>Client<\/b><\/p>\n<p><span style=\"font-weight: 400;\">clientTime = Timestamp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Password = letmein<\/span><\/p>\n<p><span style=\"font-weight: 400;\">requestPassword = sha1(Password + serverDigest)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">requestPassword = sha1(letmein + 8a2ca83d614812d6fa9d49650601b143baf8ef66)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">requestPassword = sha1(letmein8a2ca83d614812d6fa9d49650601b143baf8ef66)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">requestPassword = d738f7baa6a3fa5c3013dedea9ef76831e59469b<\/span><\/p>\n<p><b>Client to Server (Request)<\/b><\/p>\n<p><span style=\"font-weight: 400;\">&gt; Get \/?requestPassword=d738f7baa6a3fa5c3013dedea9ef76831e59469b&amp;clientTime=Timestamp<\/span><\/p>\n<p><b>Server<\/b><\/p>\n<p><span style=\"font-weight: 400;\"># Is request too old? If no, continue<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If clientTime+60 &lt; Timestamp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Continue<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Else<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Go Away<\/span><\/p>\n<p><span style=\"font-weight: 400;\"># Recompute server, this time with the associated password.<\/span><\/p>\n<p><b>Server Hash Recompute<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Timestamp = 999<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Secret = \u201cSecret\u201d<\/span><\/p>\n<p><span style=\"font-weight: 400;\">preDigest = \u201c999xSecret\u201d<\/span><\/p>\n<p><span style=\"font-weight: 400;\">serverDigest = sha1(\u201c999xSecret\u201d)<\/span><\/p>\n<p><span style=\"font-weight: 400;\"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8a2ca83d614812d6fa9d49650601b143baf8ef66<\/span><\/p>\n<p><span style=\"font-weight: 400;\">serverDigestWithPassword = sha1( \u201cletmein\u201d + \u201c8a2ca83d614812d6fa9d49650601b143baf8ef66\u201d)<\/span><\/p>\n<p><span style=\"font-weight: 400;\"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d738f7baa6a3fa5c3013dedea9ef76831e59469b<\/span><\/p>\n<p><span style=\"font-weight: 400;\"># requestPassword came from client<\/span><\/p>\n<p><span style=\"font-weight: 400;\">clientDigestWithPassword = requestPassword<\/span><\/p>\n<p><span style=\"font-weight: 400;\">if clientDigestWithPassword == serverDigestWithPassword<\/span><\/p>\n<p><em><strong>You\u2019re in! YAY!<\/strong><\/em><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There&#8217;s been many DIY&nbsp;IoT&nbsp;garage door openers but none of them offered the level of security that is required to secure my home. While it&#8217;s true that most are &#8220;good enough&#8221; placed behind a secure Wifi router, that level of security is unacceptable for a device that is on the publicly facing internet. I trust this device enough where the URL&hellip;<\/p>\n","protected":false},"author":1,"featured_media":43,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"wprm-recipe-roundup-name":"","wprm-recipe-roundup-description":"","footnotes":""},"categories":[15],"tags":[],"class_list":["post-4","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-iot"],"gutentor_comment":0,"jetpack_featured_media_url":"https:\/\/www.casler.org\/wordpress\/wp-content\/uploads\/2016\/04\/img_6583.jpg","_links":{"self":[{"href":"https:\/\/www.casler.org\/wordpress\/wp-json\/wp\/v2\/posts\/4","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.casler.org\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.casler.org\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.casler.org\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.casler.org\/wordpress\/wp-json\/wp\/v2\/comments?post=4"}],"version-history":[{"count":0,"href":"https:\/\/www.casler.org\/wordpress\/wp-json\/wp\/v2\/posts\/4\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.casler.org\/wordpress\/wp-json\/wp\/v2\/media\/43"}],"wp:attachment":[{"href":"https:\/\/www.casler.org\/wordpress\/wp-json\/wp\/v2\/media?parent=4"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.casler.org\/wordpress\/wp-json\/wp\/v2\/categories?post=4"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.casler.org\/wordpress\/wp-json\/wp\/v2\/tags?post=4"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}