A proper social site for the BDSM community

Thursday, 23 April, Year 7 d.Tr. | Author: Mircea Popescu

I. Use javacript to

  1. Locally generate a (RSA) public-private keypair. Store both as base64 modulii in separate cookiesii.
  2. Decrypt all elements sent encrypted to the local privkey and inject them into the DOM.
  3. Encrypt all submitted elements (text and pictures) going out through POST requests. Keep state of the list of foreign keys to which material should be encrypted.

II. Use whatever you use to host a website interfacing with I. above. The website should at a minimum offer

  1. a plaintext meet and greet space,
  2. a means for users to sort and be sorted into groups,
  3. a means to readily update content once intended recipients change.

All binary resources (ie images, videos, whatever) should be proxied via single use URL (once a GET request is served for that URL, it is inactivated. All text resources should be injected in the DOM locally, after having been decrypted locally via js.

This arrangement is not particularly bandwidth intensive (at least in the case of text, encryption serves as de-facto compression) and not particularly CPU intensive (users do most of the heavy lifting locally, so you get to leverage the pooled CPU of the community). It is very much legally immune : the operator can never be served a supoena of any particular utility, seeing how the website database servers merely host encrypted material to which the operator does not hold the key.

Open for comments.

———
  1. See Hanewinkel's tool for this purpose - notice that he also has a javascript encryption implementation on the other page there. []
  2. Note that the hardening of the privkey bearing cookie is a very iffy problem - I sadly don't know enough about the whole webshitstack to specify this correctly. Please help. []
Category: Job Board
Comments feed : RSS 2.0. Leave your own comment below, or send a trackback.

29 Responses

  1. This is, unsurprisingly, a much better idea than mine:

    http://qntra.net/2015/04/theymos-complies-with-yet-another-subpoena/#comment-18827

    because it completely removes the need to write separate native or Java, Air, whatever clients to access a forum, and provides the same level of owner deniability and user privacy, in browsers everyone already runs by default.

    Its incredible, though not surprising, that Discourse hasn't built its platform to do this from the start; they've concentrated only on the sheen and not the ever present fundamental threat of storing messages in plaintext.

  2. Mircea Popescu`s avatar
    2
    Mircea Popescu 
    Thursday, 23 April 2015

    The only way something like this can be financed is via Bitcoin's MPEx. Obviously USG's VC circus wouldn't touch anything actually functional in regards to privacy with someone else's ten foot pole. So no, it's not surprising they failed.

  3. What happens if the cookies are cleared? How would you recreate the keyset in a deterministic manner with enough entropy? Ask the user to re-enter his password?

  4. Mircea Popescu`s avatar
    4
    Mircea Popescu 
    Thursday, 23 April 2015

    Ask the user to save his cookies in a file somewhere.

    If they're (well, the privkey) ever cleared he's starting a new account.

  5. Idea: most systems (yes even Windows) have ssh in some form or another. Have ssh generate a keypair, then the user can just paste the keys into his browser cookie interface.

  6. Mircea Popescu`s avatar
    6
    Mircea Popescu 
    Thursday, 23 April 2015

    I'm not so sure that's such a good idea, sounds more like a bondogle. Nevertheless, because of how js works, the user can do this at any point he feels like, the site'd never know.

  7. You'd pretty much end up with a social network of men. The inconvenience in your implementation is unbearable, platonified due to your low social intelligence.

    We could also eliminate theft of cars if only every driver would carry around his engine with him. Much brilliance, very wow.

  8. Mircea Popescu`s avatar
    8
    Mircea Popescu 
    Thursday, 23 April 2015

    Leaving aside the part where you seem to imply that women are stupid on the strength of merely being women (ironically enough, in the same breath you discuss "social intelligence") : care to explain the inconvenience ? Most people's browsers are chock full of cookies set to never expire, they don't even seem to know.

  9. Nobody implied that. The bottom line is consider the number of women who employ crypto/PGP, it is so minuscule that your BDSM community would be a faggot paradise. You are free to experiment to come to the same conclusion.

    Men are more stupid and more smart than women, which is to say women are more average whereas men range from the PGP using masterrace to the vertical bags of western meat. To us (actual) men, women are "stupid" in the sense that they do not use PGP like men of low social standing.

    The question was what happens IF the cookies are removed, not WILL they get removed, losing access to your profile once your cookies are removed or you decide to use a different machine is idiotic.

  10. William Dunne`s avatar
    10
    William Dunne 
    Thursday, 23 April 2015

    Is this a job posting? Might be interested if so.

  11. Mircea Popescu`s avatar
    11
    Mircea Popescu 
    Thursday, 23 April 2015

    @Max Your confusion is too amply stratified for my meagre patience.

    @William Dunne It is, yes.

  12. William Dunne`s avatar
    12
    William Dunne 
    Thursday, 23 April 2015

    @Max it would all be done in browser, they don't need to know they're using encryption

  13. William Dunne`s avatar
    13
    William Dunne 
    Thursday, 23 April 2015

    Oh, and as for key generation I would simply generate in JS and then encrypt them using the users password - they can then be uploaded to the server allowing the users to get a backup (automatically) while the admin doesn't have to have control. Encrypting the encryption keys.

  14. Mircea Popescu`s avatar
    14
    Mircea Popescu 
    Thursday, 23 April 2015

    This breaks the "we have nothing for you to supoena" bit. Let the users save a file, it won't KILL THEM.

  15. funkenstein`s avatar
    15
    funkenstein 
    Thursday, 23 April 2015

    You might be interested, for historical purposes, in "Applied Cryptography" - B. Schneier, Section 6.6, Protocol #3:
    "... Together, they can determine whether or not they share the same fetish. If they do, they might look forward to a happy relationship. If they don't, they can part company, secure in the knowledge that their particular personal information remains confidential. No one, not even the Secure Multiparty Computation Dating Service (TM), will ever know."

  16. I think this is a half-measure that doesn't really work.

    It suffers from the same fundamental problem blockchain.info does, subpoena the website owner, have him inject some malicious JS payload that sends back the GPG keys, wait a couple of weeks, you can now decrypt 90% of the DB.

  17. Mircea Popescu`s avatar
    17
    Mircea Popescu 
    Thursday, 23 April 2015

    @funkenstein Top kek.

    @David FRANCOIS a) this is intended to be web-safe not bitcoin-safe ; b) we're not hosting anything any further except on bulletproof hosts specifically dedicated to breaking the law (as per this) and c) user doesn't have to re-download the javascript necessarily, once he has a key he can use the old js.

  18. William Dunne`s avatar
    18
    William Dunne 
    Thursday, 23 April 2015

    The SubPoena bit can be sorted in the same way that you sorted the SEC

  19. Mircea Popescu`s avatar
    19
    Mircea Popescu 
    Thursday, 23 April 2015

    At the very least you could put up a canary I guess.

  20. Isn't this approximately how (RIP) Lavabit worked ?

  21. Mircea Popescu`s avatar
    21
    Mircea Popescu 
    Friday, 24 April 2015

    I thought lavabit had the actual keys.

  22. > I thought lavabit had the actual keys.

    It had an ssl cert, that usg for some peculiar reason demanded a copy of (would not - or could not - use their 'god mode' apparently.) But it also had something like this proposed mechanism in place. If Levison had given up the cert, the next step would have been a standard mitm where users are served a diddled js which sends back the key.

  23. Mircea Popescu`s avatar
    23
    Mircea Popescu 
    Saturday, 25 April 2015

    This is not what I recall. What I recall is that the site had an actual master key.

  24. Framedragger`s avatar
    24
    Framedragger 
    Wednesday, 18 May 2016

    Some comments:

    > I. Use javacript to
    >
    > Locally generate a (RSA) public-private keypair.

    First off: even if there was a way to verify integrity, authnenticity etc. of JS code (see below - can use Subresource Integrity if browsers support it - if not - does it not boil down to trusting the server again - because no way to "pin" a JS resource?), wouldn't users be prone to a "swap keys" kind of attack by the server? i.e.: when server is requested to provide some resource authored by some user, the server provides a *different* user key ID - one which corresponds to a keypair the compromised server had generated itself - and when the PK for that key ID is requested by user, the MitM PK is served. One would need to verify key IDs via side channels, and/or have a way of importing keypairs generated elsewhere. Both are possible, but key ID side channel verification won't be done by most users...; and as to the latter, I would dread the idea of importing my private keys to the browser (even with some way of verifying that it's all legit, web crypto API is sound, no leaks, a pinned JS resource with known hash is served, etc etc.)

    Re. ECC vs. RSA: I know that ECC may not be liked here (for good reasons - e.g. if one curve is fucked then *all* who use that curve are fucked; cf. one particular modulus in some RSA keypair is botched => only one person is fucked) - but - would ECC (implemented in web crypto API (which guarantees better PRNG than JS can ever hope to do - seriously, doing crypto in JS is usually a bad idea...), or in e.g. https://crypto.stanford.edu/sjcl/ - well-respected but possibly young-ish (though now sort of mature) library) be considered instead of RSA? Particular algorithms would have to be used for encryption, signing etc. though (such as https://cr.yp.to/ecdh.html). Would result in significantly smaller keys (especially as key size is increased: RSA modulus grows faster than elliptic curve size). The main benefit would probably be encryption/decryption speed (signing would be slower, though). Key generation time would be deterministic (cf. RSA). There are decent-looking implementations in JavaScript, but I (too?) have a *special* degree of wariness when it comes to crypto in JS (or anything in JS, for that matter). So would have to make sure implementation used is good, etc. However, maybe RSA is just simpler and more straightforward.

    That being said, SJCL may be a good choice. (Examples of RSA and ECC using SJCL: http://www-cs-students.stanford.edu/~tjw/jsbn/). I'd still be worried about getting good entropy in JS - random number generation in JS has been criticized quite a bit; it's a nuanced thing (doesn't help that the language is shit... implicit type "coercion"...) Newer browsers support web crypto: https://github.com/diafygi/webcrypto-examples ; also note general concerns re. PRNG and client-side crypto: http://stackoverflow.com/questions/1130296/generating-an-rsa-keypair-in-javascript

    One particular UX-level disadvantage would be that not all OpenPGP client applications support ECC, so if one wanted to do things with their browser-stored keys, it may not be as easy.

    Nice reading to set the mood re. crypto in JS: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/ ; + to check on current status of w3's web crypto API; use Content Security Policy etc.

    Provide hashes for JS source files if browser supports - in particular, check Subresource Integrity (https://www.w3.org/TR/SRI/ and https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) (this would allow content pinning, so to speak). Also https://www.w3.org/TR/csp-cookies/ for cookies.

    > Store both as base64 moduli in separate cookies.

    Initial iteration may as well do it this way. At the end of the day, if someone has access to local browser data, that data can be stolen. Only other storage location is html5 localStorage, but even making the (dangerous) assumption that all modern browsers support it *and* that users allow for websites to use localStorage, I don't see any advantage here. Symmetrically encrypt local cookie data with a passphrase stored on the server, decrypting on-the-fly? If someone is targetting a user of this service in particular, then this is not much more secure (and adds additional dependency for a particular backend server instance on the user's part).

    Symmetrically encrypt local cookie data using a passphrase the user has to enter (encryption/decryption done by JS)? This would be more in line with how OpenPGP clients ask for a passphrase etc.; but would this add actual security (attacker gets physical access to machine and the cookie data is not decrypted at that point in time), or would it only add to some form of appearance of additonal security?

    > Decrypt all elements sent encrypted to the local privkey and inject them into the DOM.

    > Encrypt all submitted elements (text and pictures) going out through POST requests. Keep state of the list of foreign keys to which material should be encrypted.

    Re. encrypt POST data & foreign keys: so the idea is that when user submits data (of any kind), it is encrypted to (1) the public key stored locally, and (2) to every other key taken from some list (produced from, I suppose, e.g. group members (of a group the user is part of))?

    Given how MPEx works, I wonder, would you envision here having an explicit constraint that *no* additional unencrypted user data would be stored on the server - except for their public keys? So essentially the backend serves (1) public keys as requested (identified by key ID); (2) encrypted blobs (these blobs have key IDs associated to them); and (3) *some* info for groups - map of group names and IDs? And membership info? Re. latter, not clear how the alternative (i.e. not storing user/group mappings unencrypted on the server) would work; e.g. group membership of a particular user would have to be stored encrypted with private key. (JS downloads this particular blob, now has relevant key IDs for encryption, etc.) Becomes tricky with sorting and search. If needed, server may perhaps not know of group *names*, only IDs: user1 invites user2 to group, and as part of the invite sends the group name (and additional metainfo for group if needed) to user2 (encrypted with user2's key). Issues with trust, etc. Unsure if this kind of screwing-about is needed for names only (I suppose depends on how particular/private it may get, e.g. "X town's east-side grandmas").

    > II. Use whatever you use to host a website interfacing with I. above. The website should at a minimum offer

    > a plaintext meet and greet space,

    By plaintext do you mean "just text", or "not encrypted to anyone's key"? I assume the latter?

    > a means for users to sort and be sorted into groups,

    Option for unlisted/listed groups? When user creates group, they, I assume, become its admin (for purposes of altering metainfo / description / etc as well as for adding/removing users)?

    > a means to readily update content once intended recipients change.

    As in, an easy way (in terms of interface etc.) to change content of any partiular blob by Bob when Bob is the author of that blob?

    > All binary resources (ie images, videos, whatever) should be proxied via single use URL (once a GET request is served for that URL, it is inactivated. All text resources should be injected in the DOM locally, after having been decrypted locally via js.

    Sounds good. Does this imply that you would see these binary resources as not being encrypted? I mean, this simplifies matters (viewing profiles etc) - but just to be clear - these resources are not encrypted (unless user chooses to? - for sharing with some particular group/person? - so there is a choice.)

    > This arrangement is not particularly bandwidth intensive (at least in the case of text, encryption serves as de-facto compression)

    I don't think so (re. encryption as compression). Encryption does not necessarily remove statistical redundancies (which is what compression would work on) by making the resulting data smaller. In any case, compressing first (DEFLATE is fast) and then encrypting would make sense to me, no? (Though see side channel attacks involving a "compression oracle" - hell, maybe just do encryption/decryption and no compression, at least as a first iteration).

    > and not particularly CPU intensive (users do most of the heavy lifting locally, so you get to leverage the pooled CPU of the community). It is very much legally immune : the operator can never be served a supoena of any particular utility, seeing how the website database servers merely host encrypted material to which the operator does not hold the key.

    Yeah, these are nice indeed.

  25. Mircea Popescu`s avatar
    25
    Mircea Popescu 
    Wednesday, 18 May 2016

    > no way to "pin" a JS resource?

    Wait, what ? Admittedly I'm no javascript expert, but you could obviously shasum all the files that get loaded and have samples up for display ?

    > One would need to verify key IDs via side channels

    Without getting into a complete discussion of what you say here specifically, in principle I suspect the agreement is that a proper site wouldn't work with the sort of tools the subhumans use, which is why this whole idea probably reduces to gossipd.

    > dread the idea of importing my private keys to the browser

    Yeah, this is scandalous wtf. Nevertheless - you're using OTR via say IRC without importing your private key, yes.

    > one particular modulus in some RSA keypair is botched => only one person is fucked

    Except everyone uses an exponent of fucking thirty-five. Except for the people who use one, of course.

    > be considered instead of RSA?

    The only thing considered instead of RSA is C-S.

    > random number generation in JS has been criticized quite a bit

    Quite a bit is putting it mildly.

    > One particular UX-level disadvantage would be that not all OpenPGP
    > client applications support ECC, so if one wanted to do things with
    > their browser-stored keys, it may not be as easy.

    Lord have mercy, see all the threads were we wanted to transform ssh RSA keys into pgp RSA keys and discovered that "totally by accident and chance" such a tool doth not exist and has to be written de novo, in 2016. Twenty years later.

    > html5 localStorage [...] I don't see any advantage here

    Me either. But hey, the web has "progressed" right ?

    > Symmetrically encrypt local cookie data with a passphrase stored on the server

    So you've just de-rsa'd it.

    > having an explicit constraint that *no* additional unencrypted user
    > data would be stored on the server

    This is another point where the web model dies in favour of the gossipd model.

    > By plaintext do you mean "just text", or "not encrypted to anyone's key"? I assume the latter?

    I actually meant the former.

    > As in, an easy way (in terms of interface etc.) to change content of any partiular blob by Bob when Bob is the author of that blob?

    Something like that.

    > compressing first (DEFLATE is fast) and then encrypting would make sense to me, no?

    It's what was being contemplated, "encryption is de facto compression" aims to mean "nobody's going to bother encrypting and not throw a compression in also".

  26. Framedragger`s avatar
    26
    Framedragger 
    Wednesday, 18 May 2016

    >> no way to "pin" a JS resource?

    > Wait, what ? Admittedly I'm no javascript expert, but you could obviously shasum all the files that get loaded and have samples up for display ?

    Of course, (technically) yes, however, from an actual user experience perspective, I think this "being able to shasum and compare against signed samples or whatnot" feature is not as useful as you may think it may be: if there is no way for the *browser* to pin a resource (which essentially means "trust the server first time I load the page, hash this thing and then alert user if hash has changed, and do not execute automatically in that case"), it's still dangerous. Consider that (by virtue of the whole browser stack being so fucked) when you open a page with JS in it, you're kind of "installing" and running a new app every time you load it.

    If I go to a page and my browser (being the steaming pile of shit that it is) automatically runs all it cans (seriously: did you know that browsers may attempt to eval() a file if file type is unknown, *hoping* it may be JS (and doing their discovery process this way)?? - see bashing by one James Mickens, systems engineer: http://scholar.harvard.edu/files/mickens/files/towashitallaway.pdf ), it's sort of useless if I later discover that, wait, shasum mismatch, I just executed shitty JS code. Now, I can make my browser not do that (auto execute), but I don't want to manually compare checksums every time I load a page, either.

    Can check on browser extensions etc etc, but the point is, it's nice if you can tell the browser to only trust this particular version of the file, and warn you *before* it gets any funny ideas of executing it - just that. W3C appears to have standardized such enforced resource pinning. Using this in addition to samples, and say, a nice signed message with hashes in it may be enough. (But if you run an older browser which doesn't give a fuck what it's served, god help you! But then it's your fault anyway, so.)

    > gossipd

    Yeah, maybe it does. I take it you mean http://trilema.com/2015/artifexd-a-better-ircd-rfc/ - interesting proposal. I wonder if you'd still think doing a JS version of the social site to be worth it? I stumbled upon this particular post sort of accidentally, after looking for frontend-based discussion board implementations. I'd imagine an implementation for a more generic public key + encrypted blob system, with such a BDSM community social site being a further customization of that system. Having the latter in decent less-shitty form would surely be nice.

    > The 35 exponent.

    Hah, oops, well fuck. Gonna check it (Phuctor and its findings) in more detail, this is entertaining!

    > Cramer–Shoup

    Aha. RSA seems the way to go as of now, then.

    > RNG in JS

    Yeah, fuck that shit. Web crypto API (standardized browser API) may be the way to go here (https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues e.g.), but it still feels dirty.

    >> Symmetrically encrypt local cookie data with a passphrase stored on the server

    > So you've just de-rsa'd it.

    Yeahyeah, this breaks the initial idea. (Private key would still not be handed to the server, note; but this would have implications for dependence on particular server as well as some form of legal deniability on the server's part...)

    Re. all else, gotcha. So someone is working on gossipd I take it - interesting.

    I'd still like to implement this. I don't know - maybe doing all of the above in the browser *is* futile and prone to disaster. Possibly it's still a worthy idea, I think.

    May have further follow-up points later on.

  27. Mircea Popescu`s avatar
    27
    Mircea Popescu 
    Wednesday, 18 May 2016

    > Yeah, maybe it does.

    See, thinking about it any way you wish, the upside of using a browser (random lazy derp can just go to an url) is not really a match for the upside of using a dedicated app (you can use p2p distributed hash tables for crying out loud!).

    There's just no life in this idea as originally thought out, a browser thing.

    > I take it you mean

    That, at origin, a lot of subsequent discussion in the forum hence, refining etc. Even yesterday.

    > So someone is working on gossipd I take it

    The person named has been awol for a while. But it's not fair to say people aren't working. Currently the cud of the thing is being chewed.

  28. Framedragger`s avatar
    28
    Framedragger 
    Friday, 20 May 2016

    Pardon me for being too easily excitable about these things, but maybe there really is a a point to be made when you said "the correct path is to take a decent crypto lib, a distributed-hashtable-storage thing from one of the p2p torrent tools, and make a real social media app". However, I would personally settle for some kind of federated server solution, with end-to-end encryption and RSA keypair based identities (so no (explicit, at least) trust in the server). Ideally server-to-server sync, but this can come later.

    There's XMPP, there are ways to do end-to-end encrypted group chats (e.g. what open whisper systems do (mpOTR has too many unresolved flaws iirc)), etc. Not to say that this would need to stick to XMPP in some way, but, dunno, keep it simple / reuse good things. Perhaps just interface with gnupg, generate a keypair, and use gnupg for encryption/decryption/signing; and do some very simple/straightforward content GETing / POSTing. Group membership info may be stored on server. Doesn't sound too bad of an approach. If one were to demand higher integrity/authenticity promises (in regards to e.g. group membership info stored on server), one could think of employing a public ledger for this kind of stuff.

  29. Mircea Popescu`s avatar
    29
    Mircea Popescu 
    Friday, 20 May 2016

    Explain the difference between p2p and "federated server". All p2p is flexibly "federated server" necessarily, neh ?

    GNUPG is a horrible pile of shit currently in the process of being rewritten by tmsr. I wouldn't want it reused ; I suspect most of the "good things" are in the same situation. If you read the logs for the past coupla years you'll see we had started from your position, and slowly discovered that no, the stack is rotten to the core, and almost everything's either entirely useless or in need of a full rewrite.

Add your cents! »
    If this is your first comment, it will wait to be approved. This usually takes a few hours. Subsequent comments are not delayed.