<story><title>Show HN: 1-FPS encrypted screen sharing for introverts</title><url>https://1fps.video/</url><text>I wanted to show you something I was hacking on for the last few weeks.&lt;p&gt;I tired of sharing screen via Google Meet with 1-hour limitation, with Zoom and 40-minute limitation, etc. With paid Slack subscription. And often times I just needed to screenshare with no audio.&lt;p&gt;So I ended up with my own solution - no registration, low memory, low CPU, low tek 1 fps encrypted screen sharing. Currently sharing only the main screen (good for laptop users).&lt;p&gt;It&amp;#x27;s very raw in terms of infrastructure, since I&amp;#x27;m not counting bytes (yikes!), everything works on my own dedicated server. But the service itself has been tested, we&amp;#x27;ve been sharing screens for countless hours. All sessions last for 48 hours, then it gets removed with all remaining info.&lt;p&gt;Every new frame replaces the other, and everything is end-to-end encrypted so even server owners and operators won&amp;#x27;t be able to see what are you sharing.&lt;p&gt;There is also no tracking, except the main page - and I use my own analytics. Sessions are not getting tracked and never will be, and observability currently is not in place.&lt;p&gt;Again, this is a true one-person side hacking project I hope (but I have serious doubts) I might need to scale if it&amp;#x27;s getting traction to support more users.</text></story><parent_chain><item><author>red0point</author><text>I feel like there are so many pitfalls when designing this - is there something standard and trusted (would TLS work?) that you could build your application on top of?</text></item><item><author>vngzs</author><text>Good job releasing your project! It&amp;#x27;s a cool idea and surprisingly minimalist. That said, I&amp;#x27;ve found a number of cryptographic flaws in the application source. This should not be used in instances where the encryption is mission-critical.&lt;p&gt;1) You generate a random key [0] and then feed it into PBKDF2 [1] to generate a 32-byte AES-GCM key. If you can generate 32 random bytes instead of 10 reduced-ASCII characters and a key stretch, just do that. PBKDF2 is for turning a password into a key, and it&amp;#x27;s far from the recommended algorithm nowadays; prefer scrypt if you need to do this sort of thing.&lt;p&gt;2) AES-GCM with random 12-byte nonces. Never use random IVs with GCM; this breaks the authentication [2] [3]. Given the pitfalls of AES-GCM with respect to random nonces, you might prefer switching to XSalsa20+Poly1305. The advantage of XSalsa is it has an extended nonce length, so you can use random nonces without fear.&lt;p&gt;3) Random key derivation with a restricted character set can make brute force attacks easier. You should have a 256-bit random key, and if you want that key to be within a certain character set, then &lt;i&gt;encode&lt;/i&gt; the byte output from the CSPRNG using that character set.&lt;p&gt;4) 1fps achieves symmetric key distribution via a URL with a fragment identifier (&amp;quot;#&amp;quot;) which IIRC is not sent to the server. Therefore it assumes you have a secure key distribution channel - the link contains the key, so it&amp;#x27;s important that only the intended recipient can view the part after the &amp;quot;#&amp;quot;. If the server is truly malicious, it can deploy client-side Javascript to send the fragment to the server, allowing the server to access the key (and thus cleartext communication).&lt;p&gt;[0]: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;1fpsvideo&amp;#x2F;1fps&amp;#x2F;blob&amp;#x2F;main&amp;#x2F;1fps.go#L99&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;1fpsvideo&amp;#x2F;1fps&amp;#x2F;blob&amp;#x2F;main&amp;#x2F;1fps.go#L99&lt;/a&gt;&lt;p&gt;[1]: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;1fpsvideo&amp;#x2F;1fps&amp;#x2F;blob&amp;#x2F;main&amp;#x2F;1fps.go#L287&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;1fpsvideo&amp;#x2F;1fps&amp;#x2F;blob&amp;#x2F;main&amp;#x2F;1fps.go#L287&lt;/a&gt;&lt;p&gt;[2]: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;eprint.iacr.org&amp;#x2F;2016&amp;#x2F;475.pdf&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;eprint.iacr.org&amp;#x2F;2016&amp;#x2F;475.pdf&lt;/a&gt;&lt;p&gt;[3]: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;soatok.blog&amp;#x2F;2020&amp;#x2F;05&amp;#x2F;13&amp;#x2F;why-aes-gcm-sucks&amp;#x2F;&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;soatok.blog&amp;#x2F;2020&amp;#x2F;05&amp;#x2F;13&amp;#x2F;why-aes-gcm-sucks&amp;#x2F;&lt;/a&gt;</text></item></parent_chain><comment><author>vngzs</author><text>I assume there&amp;#x27;s TLS in the server connection already, but the encryption here is to make the communication unavailable to the server for decryption, so &amp;quot;bare&amp;quot; TLS does not solve the problem.&lt;p&gt;With TLS you need pubkeys you can trust (the certificate authority hierarchy provides that trust for the open Internet) or you&amp;#x27;re vulnerable to MITM. You could potentially share pubkeys using a similar out-of-band mechanism to that currently used for symmetric key distriubtion, and tunnel that TLS connection through the server&amp;#x27;s shared comms channel. That would work OK for two parties, but it becomes significantly more cumbersome if you want three or more, since each TLS session is a pairwise key exchange. Notably, however, this would not transit secret keys through server-controlled web pages where they could be available to Javascript. Something like Noise [0] might also be useful for a similar pubkey model.&lt;p&gt;Unfortunately, this kind of cryptography engineering is &lt;i&gt;hard&lt;/i&gt;. Key distribution and exchange is &lt;i&gt;hard&lt;/i&gt;. There isn&amp;#x27;t much of a way around learning the underlying material well enough to find this sort of issue yourself, but misuse-resistant libraries can help. Google&amp;#x27;s Tink [1] is misuse-resistant and provides a handful of blessed ways to do things such as key generation, but I&amp;#x27;m not sure if it&amp;#x27;s suitable outside of cloud deployments with KMS solutions. nacl&amp;#x2F;secretbox handles straight encryption&amp;#x2F;decryption with sound primitives, but it still requires a correct means of key generation [2] &lt;i&gt;and&lt;/i&gt; distribution.&lt;p&gt;[0]: &lt;a href=&quot;http:&amp;#x2F;&amp;#x2F;www.noiseprotocol.org&amp;#x2F;noise.html&quot; rel=&quot;nofollow&quot;&gt;http:&amp;#x2F;&amp;#x2F;www.noiseprotocol.org&amp;#x2F;noise.html&lt;/a&gt;&lt;p&gt;[1]: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;tink-crypto&amp;#x2F;tink-go&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;tink-crypto&amp;#x2F;tink-go&lt;/a&gt;&lt;p&gt;[2]: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;pkg.go.dev&amp;#x2F;golang.org&amp;#x2F;x&amp;#x2F;crypto&amp;#x2F;nacl&amp;#x2F;secretbox&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;pkg.go.dev&amp;#x2F;golang.org&amp;#x2F;x&amp;#x2F;crypto&amp;#x2F;nacl&amp;#x2F;secretbox&lt;/a&gt;</text></comment>
<story><title>Show HN: 1-FPS encrypted screen sharing for introverts</title><url>https://1fps.video/</url><text>I wanted to show you something I was hacking on for the last few weeks.&lt;p&gt;I tired of sharing screen via Google Meet with 1-hour limitation, with Zoom and 40-minute limitation, etc. With paid Slack subscription. And often times I just needed to screenshare with no audio.&lt;p&gt;So I ended up with my own solution - no registration, low memory, low CPU, low tek 1 fps encrypted screen sharing. Currently sharing only the main screen (good for laptop users).&lt;p&gt;It&amp;#x27;s very raw in terms of infrastructure, since I&amp;#x27;m not counting bytes (yikes!), everything works on my own dedicated server. But the service itself has been tested, we&amp;#x27;ve been sharing screens for countless hours. All sessions last for 48 hours, then it gets removed with all remaining info.&lt;p&gt;Every new frame replaces the other, and everything is end-to-end encrypted so even server owners and operators won&amp;#x27;t be able to see what are you sharing.&lt;p&gt;There is also no tracking, except the main page - and I use my own analytics. Sessions are not getting tracked and never will be, and observability currently is not in place.&lt;p&gt;Again, this is a true one-person side hacking project I hope (but I have serious doubts) I might need to scale if it&amp;#x27;s getting traction to support more users.</text></story><parent_chain><item><author>red0point</author><text>I feel like there are so many pitfalls when designing this - is there something standard and trusted (would TLS work?) that you could build your application on top of?</text></item><item><author>vngzs</author><text>Good job releasing your project! It&amp;#x27;s a cool idea and surprisingly minimalist. That said, I&amp;#x27;ve found a number of cryptographic flaws in the application source. This should not be used in instances where the encryption is mission-critical.&lt;p&gt;1) You generate a random key [0] and then feed it into PBKDF2 [1] to generate a 32-byte AES-GCM key. If you can generate 32 random bytes instead of 10 reduced-ASCII characters and a key stretch, just do that. PBKDF2 is for turning a password into a key, and it&amp;#x27;s far from the recommended algorithm nowadays; prefer scrypt if you need to do this sort of thing.&lt;p&gt;2) AES-GCM with random 12-byte nonces. Never use random IVs with GCM; this breaks the authentication [2] [3]. Given the pitfalls of AES-GCM with respect to random nonces, you might prefer switching to XSalsa20+Poly1305. The advantage of XSalsa is it has an extended nonce length, so you can use random nonces without fear.&lt;p&gt;3) Random key derivation with a restricted character set can make brute force attacks easier. You should have a 256-bit random key, and if you want that key to be within a certain character set, then &lt;i&gt;encode&lt;/i&gt; the byte output from the CSPRNG using that character set.&lt;p&gt;4) 1fps achieves symmetric key distribution via a URL with a fragment identifier (&amp;quot;#&amp;quot;) which IIRC is not sent to the server. Therefore it assumes you have a secure key distribution channel - the link contains the key, so it&amp;#x27;s important that only the intended recipient can view the part after the &amp;quot;#&amp;quot;. If the server is truly malicious, it can deploy client-side Javascript to send the fragment to the server, allowing the server to access the key (and thus cleartext communication).&lt;p&gt;[0]: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;1fpsvideo&amp;#x2F;1fps&amp;#x2F;blob&amp;#x2F;main&amp;#x2F;1fps.go#L99&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;1fpsvideo&amp;#x2F;1fps&amp;#x2F;blob&amp;#x2F;main&amp;#x2F;1fps.go#L99&lt;/a&gt;&lt;p&gt;[1]: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;1fpsvideo&amp;#x2F;1fps&amp;#x2F;blob&amp;#x2F;main&amp;#x2F;1fps.go#L287&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;1fpsvideo&amp;#x2F;1fps&amp;#x2F;blob&amp;#x2F;main&amp;#x2F;1fps.go#L287&lt;/a&gt;&lt;p&gt;[2]: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;eprint.iacr.org&amp;#x2F;2016&amp;#x2F;475.pdf&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;eprint.iacr.org&amp;#x2F;2016&amp;#x2F;475.pdf&lt;/a&gt;&lt;p&gt;[3]: &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;soatok.blog&amp;#x2F;2020&amp;#x2F;05&amp;#x2F;13&amp;#x2F;why-aes-gcm-sucks&amp;#x2F;&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;soatok.blog&amp;#x2F;2020&amp;#x2F;05&amp;#x2F;13&amp;#x2F;why-aes-gcm-sucks&amp;#x2F;&lt;/a&gt;</text></item></parent_chain><comment><author>yyyfb</author><text>I guess TLS has a dependency on the public key infrastructure (eg Let&amp;#x27;s Encrypt, or whoever issues wifey accepted certs). Which makes end to end encryption between users harder (most of this stuff is intended for server auth and encryption)?&lt;p&gt;But otherwise big +1 not to reimplement crypto when the are alternatives. Another option for secret key stuff might be ssh?</text></comment>