[HN Gopher] Show HN: 1-FPS encrypted screen sharing for introverts
___________________________________________________________________
Show HN: 1-FPS encrypted screen sharing for introverts
I wanted to show you something I was hacking on for the last few
weeks. 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. 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). It's very raw in terms of infrastructure, since I'm not
counting bytes (yikes!), everything works on my own dedicated
server. But the service itself has been tested, we've been sharing
screens for countless hours. All sessions last for 48 hours, then
it gets removed with all remaining info. Every new frame replaces
the other, and everything is end-to-end encrypted so even server
owners and operators won't be able to see what are you sharing.
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. Again, this is a true
one-person side hacking project I hope (but I have serious doubts)
I might need to scale if it's getting traction to support more
users.
Author : RomanPushkin
Score : 184 points
Date : 2024-08-06 17:36 UTC (5 hours ago)
(HTM) web link (1fps.video)
(TXT) w3m dump (1fps.video)
| popcalc wrote:
| # github.com/go-vgo/robotgo In file included from
| go/pkg/mod/github.com/go-vgo/robotgo@v0.110.1/key.go:15:
| ./key/keypress_c.h:22:18: fatal error: X11/extensions/XTest.h: No
| such file or directory 22 | #include <X11/extensions/XTest.h> |
| ^~~~~~~~~~~~~~~~~~~~~~~~ compilation terminated.
|
| https://github.com/go-vgo/robotgo?tab=readme-ov-file#require...
|
| There are some prereqs not listed your page. On Mint 22 I had to
| install the libxtst-dev package.
| RomanPushkin wrote:
| Thanks, I will update docs. "robotgo" has some issues on
| Windows, I am currently looking into some of them.
| burkaman wrote:
| What is your use case for screensharing without audio? I can't
| figure out when that would be useful, you have to communicate
| with the other person somehow.
| skulk wrote:
| From TFA:
|
| > 1fps.video is perfect for introverts and remote workers who
| prefer sharing their screen without the pressure of audio or
| video calls. It's a versatile solution that works alongside any
| team chat application you're already using.
|
| It seems closer to "text chat while sending screenshots" than
| "share screen in a voice call." I can see why some would prefer
| this.
| burkaman wrote:
| I get that, but it's also designed for sharing your entire
| laptop screen, so you'd have to either switch back and forth
| between code and chat, or take up half the screen with your
| chat app, both of which seem like they would be pretty
| disruptive to the actual screensharing.
|
| It seems like it would be better to just send a screenshot
| and then discuss, so the other person doesn't have to watch
| you typing messages to them instead of looking at the actual
| thing you want to share.
| theamk wrote:
| that's what I thought as well, but then I read this part:
|
| > we use WebSocket-based cursor tracking, providing smooth,
| near 30 FPS pointer movement for precise demonstrations.
|
| This part does not seem to support that use case, you don't
| need 30 FPS pointer tracking for text chat.. Moreover, it'd
| be actively bad, as the cursor is likely to be pointing to
| the text chat window.
| kirykl wrote:
| Scammers use no audio screen sharing while on the phone with a
| mark
| nottorp wrote:
| And disgusting extroverts need full video and audio to ...
| feel complete?
| RomanPushkin wrote:
| There are many. For example, you're leaving your home computer
| and going to work. Save a link and see what's going on there.
| The same for remote desktops.
|
| Another use case if when you have a long-running meeting, and
| still need to share. I found I sometimes just do not sit and
| listen for those 1-2 hours meetings, but prefer to code.
|
| And for those of us who just don't like audio, like myself. I
| have many students who I am willing to help, but I don't wanna
| get audio-involved. My voice chat is not a very parallelable
| resource.
| burkaman wrote:
| Monitoring a remote machine makes a lot of sense. I'm still
| not totally getting how it can work for live collaboration,
| but if it works for you that's great. I do love the
| minimalist efficiency.
| culi wrote:
| I don't think it's meant for live collaboration. Given that
| the OP is pretty focused on overcoming time restrictions,
| all-day remote machine monitoring seems like exactly the
| kind of use case they had in mind.
| wrs wrote:
| What's the 30FPS cursor tracking for, then?
| browningstreet wrote:
| I think adding audio would open interesting use cases though.
| People hate video, but 1fps isn't video. Audio still feels
| like an compelling feature. IMO..
| remram wrote:
| > leaving your home computer and going to work. Save a link
| and see what's going on there
|
| What could be going on when you're not home?
|
| If this is meant as a security tool, the fact you have to
| look at it is a non-starter.
|
| If this is meant as anything else, why wouldn't you use VNC?
| dheera wrote:
| VNC doesn't even share your screen, it creates its own
| offscreen screen and doesn't even load your desktop, and
| uses some unusable minimalist window manager with a stupid
| X cursor. Yeah I could probably figure out how to get it to
| work but it's a chore. Terrible product design.
|
| I've been wanting to create something WebRTC based, I'm not
| happy with either VNC or RDP.
| Dwedit wrote:
| On Windows, you do share the screen. I haven't seen any
| VNC servers that give you a new session like Terminal
| Services would.
|
| On Linux, I've used both kinds of VNC server. One does
| start a new X instance, while the other one shares your
| main X instance. At the time I tried it, it was
| "TightVNCServer" to get a new X instance, and "X11vnc" to
| share the existing session.
| imagetic wrote:
| I love it.
|
| Our workflow is built around removing the need for an office and
| technical infrastructure. We have live streams of our timeline
| output (video editing) and an open comms channel. Most of our
| team is pretty introverted, so it's a push to talk system. We
| mostly just leave notes in the chat if it doesn't warrant a full
| discussion.
|
| Crude solutions are often the ones that get adopted.
| RomanPushkin wrote:
| I'm happy to hear that. I've just open sourced the server part,
| so you can play with it a little bit more! I will improve docs
| over the time, so it's easier to follow.
| zokier wrote:
| could be interesting concept to try to make some heuristics for
| picking _which_ frame to use; just blindly picking always the
| latest frame is unlikely to be ideal, instead you might want to
| pick frames where there is little movement, or no ongoing
| animations, or some other similar metrics. if you want to be
| super fancy, you could try to do this analysis per-window and
| then construct some sort of aggregate for the whole frame.
| eddd-ddde wrote:
| I think this may defeat the purpose of minimal compute
| utilisation.
|
| It definitely sounds like a great idea and an interesting
| problem.
| RomanPushkin wrote:
| oh, I like it actually! I had idea to scan the screen with 5-10
| pixel sparse 100x100 matrix at the point where the change has
| been found previously to detect a possible screen change.
| philsnow wrote:
| > you could try to do this analysis per-window and then
| construct some sort of aggregate for the whole frame
|
| This seems like it could get into the area of smartphone
| "cameras" that do so much computation on the output of the
| light sensors that it can hardly be called photography [0].
| It's a cool idea (in chess I've heard a similar idea called
| "quiescence search"[1]), but probably not worth the trouble.
|
| [0]
| https://old.reddit.com/r/Android/comments/11nzrb0/samsung_sp...
|
| [1] https://en.wikipedia.org/wiki/Quiescence_search
| KomoD wrote:
| I'm having issues with the cursor tracking, I don't know if it's
| because I have multiple monitors or something like that?
|
| Here's a pic, the ring is where my cursor actually is
| https://i.imgur.com/TvzskjS.png
| RomanPushkin wrote:
| Thanks, you have my promise that for every major use case there
| is going to be a fix. Feel free to check out at a later time if
| has been fixed or not. I appreciate the feedback
| vngzs wrote:
| Good job releasing your project! It's a cool idea and
| surprisingly minimalist. That said, I've found a number of
| cryptographic flaws in the application source. This should not be
| used in instances where the encryption is mission-critical.
|
| 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's far from the recommended algorithm nowadays; prefer scrypt
| if you need to do this sort of thing.
|
| 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.
|
| 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 _encode_ the byte output from the CSPRNG using that
| character set.
|
| 4) 1fps achieves symmetric key distribution via a URL with a
| fragment identifier ("#") 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's important that only the
| intended recipient can view the part after the "#". 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).
|
| [0]: https://github.com/1fpsvideo/1fps/blob/main/1fps.go#L99
|
| [1]: https://github.com/1fpsvideo/1fps/blob/main/1fps.go#L287
|
| [2]: https://eprint.iacr.org/2016/475.pdf
|
| [3]: https://soatok.blog/2020/05/13/why-aes-gcm-sucks/
| RomanPushkin wrote:
| That's pretty cool and this is exactly why I am here :) To have
| this kind of advice. I'll implement these changes as soon as I
| can.
| mass_and_energy wrote:
| This is such a healthy interaction, it makes me so happy to
| see people lifting each other up like this
| vngzs wrote:
| You will still need to get the nonce and key generation
| right, but I'd recommend using Golang's nacl/secretbox [0]
| for a project such as this. It's designed to be relatively
| misuse-resistant compared to using underlying primitives
| directly, and under the hood it's XSalsa20+Poly1305 - so you
| can use random nonces with negligible collision risk.
|
| [0]: https://pkg.go.dev/golang.org/x/crypto/nacl/secretbox
| red0point wrote:
| 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?
| yyyfb wrote:
| I guess TLS has a dependency on the public key infrastructure
| (eg Let'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)?
|
| But otherwise big +1 not to reimplement crypto when the are
| alternatives. Another option for secret key stuff might be
| ssh?
| dathery wrote:
| It would be hard to do end-to-end TLS (where the server
| proxies the raw connection) because
|
| (a) you can't share one TLS connection to the host between
| multiple clients; if you wanted multi-client support while
| preserving end-to-end TLS, the host would need to maintain a
| TLS connection with each client and waste bandwidth re-
| uploading the same image
|
| (b) there is no client software requirement, so you would
| have to do the TLS decryption clientside in the browser
| (maybe via WASM) unless you're OK with having viewers
| download software
| beltsazar wrote:
| > there are so many pitfalls when designing this
|
| Agree. When people hear the adage "don't roll your own
| crypto", they often think it refers to crypto primitives
| only. In reality, it's also hard to design a secure crypto
| protocol, even if the underlying crypto primitives are
| secure.
| vngzs wrote:
| I assume there's TLS in the server connection already, but
| the encryption here is to make the communication unavailable
| to the server for decryption, so "bare" TLS does not solve
| the problem.
|
| With TLS you need pubkeys you can trust (the certificate
| authority hierarchy provides that trust for the open
| Internet) or you'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'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.
|
| Unfortunately, this kind of cryptography engineering is
| _hard_. Key distribution and exchange is _hard_. There isn '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's Tink [1] is misuse-
| resistant and provides a handful of blessed ways to do things
| such as key generation, but I'm not sure if it's suitable
| outside of cloud deployments with KMS solutions.
| nacl/secretbox handles straight encryption/decryption with
| sound primitives, but it still requires a correct means of
| key generation [2] _and_ distribution.
|
| [0]: http://www.noiseprotocol.org/noise.html
|
| [1]: https://github.com/tink-crypto/tink-go
|
| [2]: https://pkg.go.dev/golang.org/x/crypto/nacl/secretbox
| MoonObserver wrote:
| > 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.
|
| Those papers are a bit over my head. Could you please explain
| what's wrong with using random IVs here? What should we do
| instead (assuming we can only use GCM, and not switch to
| chacha)
| jszymborski wrote:
| Not an expert, but this is my understanding.
|
| 1. It is necessary for nonces to never be re-used for a given
| key lest you open yourself to a certain class of attacks that
| can decode all messages using that key. This is specific to
| AES-GCM due to how it internally reuses nonces.
|
| 2. AES-GCM uses very small nonces, making the probability of
| randomly using the same nonce unacceptably as the number of
| messages encoded with a given key increases (as it would with
| each frame sent on 1fps).
|
| You can avoid all this by using a different primitive with a
| longer nonce such as XSalsa (a version of Salsa with a
| 192-bit nonce)
| conradludgate wrote:
| There's two issues.
|
| Background: the key+IV define a keystream which is xor-ed
| against the message. The same key+IV generate the same
| keystream. Thus you can XOR two cipher texts and reveal
| information from the two plaintext.
|
| AES-GCM is authenticated encryption. To combat known-
| ciphertext-attacks, you want to have authenticated cipher
| texts. AES-GCM specifically is vulnerable to an attack with a
| reused IV to recover the authentication key. Allowing you to
| forge authentication tags and employ a KCA.
|
| The solution, if you're stuck with aes, is to switch to XAES-
| GCM or better AES-GCM-SIV. Alternatively you must use a
| counter or checkes system to not reuse IV. Since this is in
| the context of 1fps, you could use unix timestamp + random
| bytes to reduce the chance of collisions.
| lulzury wrote:
| Thank you for sharing this and recommending XSalsa20+Poly1305.
| I have always been interested in cryptography, so learning
| about the many ways why one shouldn't roll their own crypto AND
| protocol is very cool.
|
| Out of curiosity, is the primary reason you don't recommend
| fixing the nonce issue in this specific case due primarily to
| the pitfalls in doing so or is it more nuanced and related to
| the general issues mentioned in the articles above?
|
| A naive perspective could be that one uses AES-GCM because it
| is used in so many places, such as TLS or SRTP, and someone who
| is not very well versed in cryptography assumes it can be the
| way to go.
| vngzs wrote:
| AES-GCM has more issues than merely the nonce reuse in the
| context of random nonces. For instance, the short tag
| issue[0] leaks authentication (not encryption) keys after a
| probabilistic "forged" message.
|
| In general, the move in modern cryptography engineering is to
| assume the end user does not know what they are doing. For
| GCM, you have to get the nonces right and you need the right
| tag length, and the design uses lookup tables so it's prone
| to timing attacks in many implementations.
|
| Later on I didn't just recommend an algorithm but a specific
| implementation (at least if we can find a better method of
| symmetric key distribution): nacl/secretbox [1]. This is a
| cryptographic library designed to be _misuse-resistant_ , a
| property of cryptographic designs that makes implementation
| errors more difficult. nacl is a few years behind the curve
| inasmuch as it arguably gives the end-user too much control
| over key generation, but it permits random nonces (being
| based upon XSalsa) and provides a simple API that is
| difficult to mess up.
|
| AES-GCM is secure with a correct implementation, but to build
| a correct implementation you often need to know the specific
| library inputs and configuration settings to produce your
| desired outcome. Something like secretbox doesn't give you
| those options: you get one relatively secure configuration
| ... and that's it!
|
| [0]: https://csrc.nist.gov/csrc/media/projects/block-cipher-
| techn...
|
| [1]: https://pkg.go.dev/golang.org/x/crypto/nacl/secretbox
| NotPractical wrote:
| Do you have a recommendation to address #4? That seems like an
| intrinsic problem for web apps, see also ProtonMail.
| vngzs wrote:
| You're very right, and it's a challenging problem to resolve
| in general webapps. Protonmail is almost surprising: it's
| _supposed_ to be end-to-end encrypted, but it 's not end-to-
| end encrypted in the presence of a malicious server. If, say,
| a government order compelled Protonmail to deploy a backdoor
| only when a particular client visited the site, most users
| would be unaffected and the likelihood of discovery would be
| low.
|
| The technical explanation for this issue is that the client-
| side Javascript in our webapp is _trusted_. To quote the late
| Ross Anderson [0, pg. 13], "a _trusted_ system or component
| is one whose failure can break the security policy. " In this
| case, our security policy is that the server must not be
| capable of viewing our screenshots. Our goal is to make that
| trusted Javascript more _trustworthy_ : that is, closer to a
| system that _can 't_ fail.
|
| We're at an advantage in this case: there's an open-source
| application on GitHub with eyeballs[1] on it that users must
| run on their endpoint machines. Given that we already have
| source-available local code running, we could instead serve
| the UI from the local Go application and use CORS[2] to
| permit access to the remote server. If the local application
| is trustworthy, and we're not fetching remote Javascript,
| then the local client UI is trustworthy and won't steal your
| keys.
|
| [0]: https://www.cl.cam.ac.uk/~rja14/book.html
|
| [1]: https://en.wikipedia.org/wiki/Linus%27s_law
|
| [2]: https://stackoverflow.com/a/45910902
| rustcleaner wrote:
| >limited proprietary GNU-nonfrenly screensharing
|
| Was Rustdesk on-radar?
| andrea76 wrote:
| Does it support wayland?
| cornholio wrote:
| Does it use WebRTC? The last time I've looked at this - and what
| stopped me from releasing a more polished MVP of the same low
| impact continuous meeting-not-a-meeting concept - is that the
| only way to scale WebRTC is to use your own paid infrastructure.
| The only peer to peer topology available WebRTC clients support
| is a star, so without a multiplexing server you are practically
| limited to a handful of peers in any session.
|
| So you are either offering a slow and very limited free service,
| or you need to pay hand over fist and burn venture capital to
| basically compete with Zoom and WebRTC. Slowing the video stream
| to very low FPS does help somewhat with scaling, but makes for a
| niche product.
|
| If you can crack P2P multiplexing and offer an unlimited free
| service, and tack on some fremium model on that, that this thing
| can take off like a rocketship, if for no other reason that every
| team leader in the world wants a continuous feed of their remote
| worker's desktop. A free and capable screen sharing app can
| become THE tool for collaboration, disrupting things like Slack
| if the right features are there.
|
| I'm seriously interested to cofound something like that, let me
| know if anything I've said makes sense to you.
| cropcirclbureau wrote:
| Ah, yes, consistent spying on workers to make managers feel
| better. How about you feed each frame to an LLM for AI powered
| productivity monitoring? How about you incorporate web cam for
| next gen AR AI companionship? How about you make it
| customizable so that managers can easily roll out and maintain
| appropriate cultural practices? Studies show synchronized boot
| clicking, twice daily, can foster excellent dedication and
| energy to the improtant taskd at hand. Zillion dollar idea
| buddy.
| walterbell wrote:
| _> every team leader in the world wants a continuous feed of
| their remote worker 's desktop._
|
| "every" -- why?
|
| Do high-performance teams have low or high trust?
| burkaman wrote:
| Please do not do this. The product you're describing would make
| the world a significantly worse place.
| 0xdeadbeefbabe wrote:
| The market would punish you too.
| pjc50 wrote:
| > if for no other reason that every team leader in the world
| wants a continuous feed of their remote worker's desktop
|
| _ahem_ GDPR?
|
| Besides, that's absolutely the sort of enterpriseware that
| should be charged for.
| formerly_proven wrote:
| 1 FPS screen sharing? Isn't that just MS Teams on a tuesday?
| andriamanitra wrote:
| From reading the code it looks like it's just taking a screenshot
| (.jpg) and sending it once a second. Does doing it that way
| actually save on bandwidth compared to modern video compression
| (that re-use information from previous frames)?
|
| I recorded a one minute video clip of me editing some code in VS
| Code (1440p 10fps, using AV1 encoding) and it was about half the
| size of 60 JPEG screenshots of the same screen. I would be
| curious to see your numbers if you've done any tests.
| AndrewKemendo wrote:
| Seems like is preventing data persistence (replace, delete) was
| chosen over minimize bandwidth (no optimization)
|
| But could easily do both if you wanted to - though I'm not sure
| it's worth the hassle. I agree that this might struggle if used
| at scale on the same IP
| Retr0id wrote:
| This was my first thought too, there's no reason not to use a
| standard codec, just configured to run at 1fps.
| RomanPushkin wrote:
| It's not only a matter of bandwidth, but a matter of CPU
| utilization. I've tried to feed screenshots to ffmpeg and other
| tools, and it's just... unusable. It works, but consumes way
| too much resources. At least on my computer (MacBook 13-inch,
| 2019).
|
| So from on side you have CPU utilization, from the other -
| network. Network is cheap, but encoding is expensive. This is
| my thinking at least. I don't have proof - only local
| experiments, but it's a really good idea to start measuring
| this.
|
| I also have other ideas in mind on how to scan the screen and
| send only parts of the screen that have been updated. Probably
| if I send only a half of the screen, it will beat the video
| encoding in terms of network. The diff algo should be very fast
| though, since we're dealing (in case of 1280x720) with
| 1280x720=914400, 914400*4 = 3.49 MB info processing in 1
| second.
|
| Also, curious to hear about video encoding efficiency vs 60x
| JPEG creation. Is it comparable?
| AndrewKemendo wrote:
| I was looking for something like this today because we're remote
| monitoring a physical test event and having an open google meet
| with recording is a mess - however we would still want to be able
| to have text chat for the interface
|
| Seems like this is a really good minimal interface - if I'm
| feeling wonky I might extend it with chat persistence somehow
|
| I am assuming any additional synchronized text or voice is done
| elsewhere like calling someone on the phone or clarification via
| text on slack right?
| RomanPushkin wrote:
| This is what I sometimes do with a friend of mine: WhatsApp
| phone call and a simple screen sharing between my laptop and
| his PC.
| fitsumbelay wrote:
| very cool idea, and the pro-introverts pitch is very interesting
|
| I really appreciate the discussion about the tech involved,
| especially non-go lang info and advice. peak HN imo
| jpeeler wrote:
| OpenDNS is reporting this domain as malware :(
|
| https://malware.opendns.com/main?url=1fps.video&server=nyc4&... -
| not sure if that's viewable elsewhere, but if so there's a report
| link there.
| Dwedit wrote:
| Moonlight Game Streaming has pretty much displaced VNC for my
| uses. It just needs some better features for things like file
| transfer, clipboard sharing, etc...
___________________________________________________________________
(page generated 2024-08-06 23:00 UTC)