Show HN: Portable Secret – How I store my secrets and communicate privately
mprimi.github.io
mprimi.github.io
This also applies to most if not all challenges mentioned by other posters. Take phishing for example, at the moment all methods to exchange information of interest that are at the same time user friendly are relatively easy to phish, be it email, discord or WhatsApp.
I still wouldn't store "top-level secrets" in here and upload this to a cloud drive and forget about it. Someone smarter than me could spot a bug in your code (or the API's code) in a year and that renders your solution vulnerable. A browser's implementation of the API could be flawed in a particular version. Someone adversarial to me could bribe a number of people to get answers to 10 different password hints. There are some other scenarios that are implementation specific, I'm sure.
All in all, great tool. I hope you find more users if you are looking for more! :)
Not looking for users TBH. :-)
re: bug in the vendor implementation of cryptography. Doesn't this apply to everything you encrypt?
There are totally use cases where having encrypted data at publicly retrievable, even well-known URIs makes sense, but there are other use cases where you want some level of network security as well.
Re your question: of course. There are some things to consider:
1. These files do seem to have some persistence on either the sender’s, the recipient‘s or a shared machine. With long persistence in several places, the risk of unwanted access is being elevated. (Cloud instances and identity providers get popped, machines get viruses, etc) 2. As mentioned by a sibling comment, the encryption is your only layer of protection. 3. Browser’s are probably one of the top three targets of vulnerability researchers at the moment. They were at the number one spot 2-3 years ago.
When a vulnerability is found in the implementation, the missing controls become a problem. Your quote about 0days is certainly correct. At some point it won’t be an 0day anymore though, and it’s hard to convince people to rummage through their hard drive to delete some files.
OP's hints are probably more generous than they need to be. (Indeed, knowing that password is name + flower + name + two-word-thing, plus the fact that there is no limit to the speed you could brute-force this, means that someone could probably make a custom dictionary and break this in a couple days.)
But you can easily have hints and make it harder. In Evernote I store a few passwords to things, and the hints are more opaque ("grey" refers to my old grey cat, for instance) but they're also all prepended with a 15-character master password that changes in subtle ways depending on the service they're used for. This isn't in the hint, it's just in my head.
Off topic, but in principle a sufficiently expensive key derivation could guard against this, right? Is there a reason why it isn't done? I wouldn't mind waiting a few minutes for my identity document to decrypt if I hardly ever access it. In that case the usability benefit of a fast key derivation algorithm seems minor.
It wouldn't even be hard to expose this functionality via a user interface -- say when a user is setting up a Portable Secret, let them click to select a security level between "low security" and "high security", where each security level corresponds to an estimated number of minutes it will take the secret to decrypt on a modern PC. Seems like it would make intuitive sense to grandma.
And with regard to the software vulnerabilities topic discussed above, as long as we're waiting a few minutes, we might as well make use of multiple key derivation algorithms in case one or more of them is shown to be weak.
Added you to the project README.
(I got a bunch of compliments for this project today, I hope you are enjoying seeing them too given we had the same idea)
https://github.com/mprimi/portable-secret/commit/3b22d2b42ba...
I'd love to hear more about this.
edit: oh, it looks like it wasn't actually drained.
- Bitcoin is hard
- Wallets come with sophisticated anonymization built-in
- Don't create the bounty wallet 20 minutes before posting on HN (if that snafu had happened today while this post was on the front page, I would have looked pretty stupid)
It wouldn't be that crazy for the browser to do the encryption part for me, right? Like, what if in the 'save this page' dialog my browser actually did the encryption, and then generated this 'self-decrypting page' for me if I checked a box saying "encrypt with password"? Would be a nice way for regular non-technical people to encrypt things and send them to each other.
I have no use for this myself but wrote a quick Node.js script which accepts an html file created by this tool and prints messages to stdout or saves a file to decrypted.ext: https://gist.github.com/andrewmackrodt/e6a5a2ea7b22d74102ba7... - it's dependency free (no npm install dependencies) and tested with Node.js 10 and above.
e.g. "docker run --rm -it -v "$PWD:/app" -w /app node:10-alpine portable-secret-decrypt.js example-image.html"
When used with the Bart's drivers license it will create the decrypted file as decrypted.jpeg to the cwd.
There’s more of a case for public-key stuff changing, but this doesn’t rely on anything public key.
No points will be awarded for citing jank that is a direct consequence of depending on proprietary, experimental, or non-standard stuff (like, "well, my Flash site worked in 2002, but now it doesn't").
One thought that I have: would there be an issue sending this file in an unsecure context where MITM is a possibility? Alice sends Bob her HTML file over an unsecured medium, and Jane intercepts this traffic, and gives Bob a modified HTML file that will report the password back to Jane. Jane can set it up so that the browser still displays the local file as it's source, but has an HTTP request in the background phone home back to Jane's server.
My scenario only works if Bob doesn't inspect the page source before entering their password, or if the modifications are sufficiently obfuscated.
I’d expect better from Jane. This is the kind of shit Mallory would pull.
To be fair, the exact same problem afflicts something like Protonmail, so calling it a toy may be too harsh.
For this persons use case though, assuming they’re not a person of interest to any “threat actors”, I wouldn’t be too worried.
This doesn't help if someone can mess with the HTML though.
- attack surface area drastically reduced. only one MITM matters now, the extension installation - requires great extension UX, to help dads know where to click
less portable than just a document, but perhaps a nice middle ground
I assume you are referring to the OP's post there but I did a double take because I know some extremely technical moms.
Your issue is not with the program being in-browser, but rather it being an online one that gets ~continually re-fetched and immediately trusted without verification.
[1] https://github.com/mprimi/portable-secret/blob/6efdb4618216f...
[2] https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypt...
[3] https://github.com/mdn/dom-examples/blob/main/web-crypto/enc...
[4] https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS#5_....
* When you decrypt then close the tab and open the tab again via the recently closed tab, the password is still there.
* Browser extensions could read the contents of the webpage.
So if anyone is going to use this, they should do it in a "clean" incognito browser without any extensions.
GPG or vim -x might be much better choices for secrets that need to be decrypted many years from now.
These are NIST-recommended algorithms, they'll be around for a while...
https://github.com/vim/vim/issues/638
To sum things up, the Vim maintainers are totally ignorant on the topic of cryptography, but what's worse is that they are highly stubborn and refuse to accept their ignorance while ignoring valid criticism from people who do know. This combination of traits does not mix well with cryptography, where doing things correctly is extremely difficult but also extremely important.
I am not totally sure whether this specific issue has been fixed since I last checked this out, but at the time Vim's encryption was totally broken and should not have been used at all.
I am not too familiar with Vim overall, but Emacs file encryption uses GPG to do all of the important stuff, and just provides a nice interface to that. I imagine Vim has something similar available at least as a third party extension. Letting something like GPG or Age handle the important stuff is a much better way of handling this!
But one story that particularly stood out was of a woman who was hit by lightning during clear weather, inside the house, through the water pipes - she was cleaning dishes at the time. So your scale might be still too small.
Annoyingly this technique uses AES-GCM (which is good!) but OpenSSL's command line tool can't cope with it: https://github.com/openssl/openssl/issues/12220
It would be nice to have a command line tool to extract these files too, then you know the implementation is correct. (Blowing my own trumpet but my very old project https://paste.sh does this.)
The parts of the web that get incompatible changes are generally stuff like nonstandard plugins (Flash being discontinued) and TLS (which isn't relevant if you're keeping some HTML file saved locally). Browsers bend over backwards to keep existing HTML/JS content working.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
That's because it only uses NIST recommended encryption, which is baked in or available in most languages.
Legacy versions of Firefox should be available in some archive, nevertheless. For additional security, you may use them on an air gapped system to decrypt our secretes. You need to trust the archive, though (as you need to trust the browser, now).
Could those crypto functions built into the browser be replaced with JavaScript implementations?
Funny thing, here in EU country, there are government apps which stills require MS Silverlight. Nice right?
Passwords:
- Easy to memorize. Pro: Does not rely on a device, can be recovered if devices stolen.
- Easy to phish. Con: Attacker can use a look-a-like page, click-jacking, and pixel extraction (frame stealing) attacks to get password & secret.
- Easy to brute force. Con: Relies on human adherence to password best practices to maintain sufficient entropy. Learning from industry that this does not work in widespread adoption. This will work for certain power users.
Cryptography:
- Uses current state of art algos. Pro: Resistant to access by known methods.
- Will become obsolete. Con: Eventually the secrets will become exposed due to advances in crypt-analysis. Mitigation: Don't store anything to remain secure for decades, shorter lived is okay.
- Secrets are encrypted once. Con: Any issue (there have been many) in WebCrypto implementation at time of encryption can not be fixed by browser upgrade (because of secret caching).
- Secrets can be extracted from page and cracked elsewhere offline. Note: Security features such as timers, throttling, guess limits can not be enforced. They must be implemented e.g. in PBKDF.
Client Side Security:
- Cached objects. Note: For example a web page with browser vulnerability can walk JS objects and get existing secrets. Browser may also cache secrets, passwords, inputs, images to disk where they are not protected.
- Web Browser WebCrypto and Same Origin Bypasses. Pro: Browsers have updates and are constantly being improved to enforce security model. Con: The direction the W3C goes in future (tens of years) is not certain and security model may change. Implementation issues in browser web APIs and Same Origin (common) can put secrets at risk.
- Secret hosting. Con: Hosting content on other servers (e.g. github) may not allow management of access control. For example hosting on one subdomain could now or in future allow JS on sister pages to interact with page and the resources loaded, enabling side-loading attacks in JS. This may not be in control of victim if they uploaded their secret to be hosted by another party.
- Trusted hosting. Con: Any untrusted source of HTML can steal the secrets, e.g. by serving malicious javascript along with the secret. This means the security of the hosting party and trust in the hosting party is required. (Note: this con was added in an edit)
> Easy to phish. Con: Attacker can use a look-a-like page, click-jacking, and pixel extraction (frame stealing) attacks to get password & secret
This to me is the most glaring "vulnerability". i.e. I use this to exchange letters with my friend Bob. Now someone impersonates me and sends a fake 'PortableSecret' to Bob that siphons out the actual password.
Clearly this is a valid vector of attack, and one I made no attempts at defending from.
The thing is... this won't happen. If I'm dealing with an attacker so sophisticated to pull this off, it's likely they have 1000 other vectors that are more effective and dangerous.
I have to keep reminding myself this is a real vector, but the fear is irrational.
As they say at DEFCON to people too concerned using their devices: "Nobody is wasting their 0day on you".
I don't think I'm a target valuable enough to attract this kind of attacker.
What's important is that other persons and organizations who may be targeted - that they choose what technology to use, knowing what kinds of attacks are possible. For example a human rights activist might very well be targeted by phishing attacks and choose not to store secrets by this method.
I am just trying to enumerate the properties so that persons/organizations can evaluate a match to their use case. I don't believe any system is perfect for all use cases and I don't hold any system to such a standard.
"Relies on human adherence to password best practices to maintain sufficient entropy. Learning from industry that this does not work in widespread adoption"
The GP's statement can be boiled down to: "users will choose poor passwords" (as in Password1!) because it has been shown time and again that "users will choose poor passwords" if left to their own devices to do so.
The 'easy to brute force' part then comes in as "for those users who choose poor passwords, this rig linked below will brute force their passwords pretty quickly":
https://gist.github.com/epixoip/a83d38f412b4737e99bbef804a27...
Note that the above performance page is a few years old, updating it for 8x of a newer Nvidia GPU should result in even more impressive performance numbers.
And in all fairness, any cryptography where a user chooses a poor password is then vulnerable to "easy to brute force" by a rig such as the one above. Not because the encryption algorithm is easy to brute force (usually it is not) but because the user picked a poor password, and that poor password itself is easy to brute force.
Don’t delude yourself. These phishing pages with mirrored login portals happen to podunk organizations all of the time.
If someone manages to get a link to your page and is interesting in the contents, duping it and sending a phishing link to the suspected password holder is a trivial spear phishing attack (with an annoyingly high success rate).
You can claim this con for literally any crypto. And I'm not actually sure it's a reasonable assumption.
Block ciphers seem to be pretty unbreakable so far. Even good ol Triple-DES is secure in practice barring some caveats (don't encrypt more than a certain amount of data)
I'd wager if I gave you a real world message encrypted with AES with a strong key it won't be broken in our lifetimes.
It is not true this con applies to all cryptography (e.g. look at TLS). It has more to do with how cryptography is configured, parameters are negotiated and keys are managed, than with point-in-time choices about algorithms. The con here is that unlike other deployments of cryptography, this one doesn't have parameter negotiation and key management - and therefore doesn't have cryptographic agility.
Re: "I'd wager that... AES..." is a also a good point. Modern cryptography has shown to be robust for decades and past their deprecation point. However, as you said, it IS a wager. There have been catastrophic failures of cryptographic primitives in the past. The con of this system is you will need to make a wager and tie yourself to the fate - you can't mitigate the risk if the catastrophic event comes or appears to be coming to pass.
This project is plenty agile, upgrading the primitive is very easy as it's not a communication protocol but a data at rest protocol.
> this one doesn't have parameter negotiation and key management
You're thinking in terms of live communication protocols between endpoints. There is no "parameter negotiation" when you are both the sender and receiver of a static ciphertext.
There is no existing remediation for protecting your existing ciphertexts against future cryptanalysis.
Many of the most interesting/effective attacks on SSL/TLS have been downgrade attacks that stem directly from the protocol's (historically) agile design.
AES-GCM is fine sure, but the password hashing function PBKDF2-HMAC-SHA1, i.e. what turns the user's weak password into the AES-key, is the opposite of state-of-the-art in this case.
has there ever been an issue that made WebCrypto produce invalid ciphertexts/hashes/PBKDF output?
Thinking of using this as the final backup, something to store 2FA backup codes/recovery codes etc, basically a way to end circular-dependency on my password manager, i suppose one would host this using free public hosting, maybe cloudflare pages on a hidden website, basically something reliable and trivial to access.
however relying on localstorage, which can be accessed by extensions worries me, but i couldn't replicate the password showing up in browser history thing(using brave).
seems the best option for my use case so far, maybe a self extracting 7zip archive with file name protection is better?
I also thought so until I suddenly forgot a master password I have been using for several years. Luckily, I was able to recollect it after several days. Then, I forgot it again.
Age, decease and head trauma can happen.
Unless I hit my head really hard, there's zero chance I will forget this passphrase.
Am attacker keen enough to bruteforce can easily copy the ciphertext, IV, and salt to a tool that doesn't have a slowdown. Or, just modify the JS to remove the artificial slowdown.
That one makes passwords vanish from ones memory quite effectively.
> I came up with Portable Secret on my own, but I have since found a few projects that do something similar.
> https://github.com/kaushalmeena/digi-cloak
> If you are aware of other similar projects, please let me know and I’ll link them here.
Digi-Cloak appears to be an in-browser steganography tool, but this project looks more like an encrypted pastebin (e.g., PrivateBin [1]).
The obvious weakness is your hosted document creator: it’s essentially impossible to defend an HTML document against a malicious domain. We can look at your GitHub repo, but there’s no guarantee that’s the exact code that’s running. If you’re an especially valuable target, you can’t even be sure that the files that you think you’re serving haven’t been tampered with.
How does a library improve portability and lifespan? I'm only using NIST-recommended encryption algorithms provided by W3C Crypto APIs.
> The obvious weakness is your hosted document creator: it’s essentially impossible to defend an HTML document against a malicious domain. We can look at your GitHub repo, but there’s no guarantee that’s the exact code that’s running.
I agree. As clearly stated in various places, this is a demo. Take the idea and fork/re-implement it for yourself.
> How does a library improve portability and lifespan? I'm only using NIST-recommended encryption algorithms provided by W3C Crypto APIs.
I’ve been writing software long enough to have been around the block a few times, and the web ecosystem hasn’t been pretty. Things get added, things get taken away, someone discovers some edge case in an API that’s not used very often and instead of being patched it’s just dropped (https://developer.chrome.com/blog/deprecating-web-sql/ or https://chromestatus.com/features#removed). Web apps shouldn’t but often do require significant maintenance.
In that context, it’s likely that something about the API that you’re using will stop working in a few years. Someone who wants to make a new document could bring things up to date and publish a new version. But existing documents? The ones used by friends and family who aren’t as technical, they’ll stop working.
The other side of the web is that the ubiquitous parts, basic HTML and JavaScript, will be supported pretty much forever. People want to see that their browser will render popular old pages, at least ones that don’t use super fancy things. Using a random encryption library to encrypt things could leave your cypher text vulnerable, but using a random decryption library (that’s verified to be able to decrypt) doesn’t have the same risks. It will, however, work pretty much forever (as long as it doesn’t rely on any browser APIs) which is ideally how long our files should last.
Congrats on building a cool thing!
To your point, the W3C Crypto library APIs might change, and break my secrets. Unlikely but possible.
I don't know that bringing in a library makes this better: it could use features/constructs of the language that get deprecated and break.
There's other factors to consider (convenience, amount of review a given implementation has gotten, etc).
Overall, agree to disagree. Using a library has slightly different tradeoffs and I can see why you are recommending it. But I stick by my choice to depend on browser APIs.
Web SQL? Now you could survey a room and ask if they think web JavaScript should have a native SQL library and probably half will say ehhh… a native SQL library where there are a thousand ways to implement it was doomed from the start
That said, algorithms may be deprecated and removed. I’ve seen that happen in crypto libraries.
To me this feels like a merger of the ideas in projects like magic-wormhole, Wormhole.app, and the (defunct) Mozilla Send. But then it adds a kind of sharchive twist using the browser as a runtime.
The original paper I saw called it Password Authenticated Key Exchange. https://www.cs.columbia.edu/~smb/papers/neke.pdf
But I think the general form is now called something like this: https://en.wikipedia.org/wiki/Password-authenticated_key_agr...
Anyway I’m posting all this not to show my erudition (I’m really stupid about cryptography) but that there’s lots of precedent for this kind of tool and maybe with a few tweaks can even be made standards-compliant. (RFC 8188 seems to contemplate some ideas like this, but the file isn’t “self-expanding”.)
Some obvious issues: sitting on a thumb drive, the file is vulnerable to unlimited attacks. And since the decryptor is in “plaintext” it could be MITMed in a way, since the decryption code can be tampered with, and a browser environment with localhost access can be tricked into doing lots of things, including sending decrypted contents to the attacker. In a SaaS there’s no MITM given transport security, and you can notice you’re getting attacked, or expire links after a number of tries / some amount of time.
But so what; the whole point here is to provide really good security with a different channel.
https://security.stackexchange.com/questions/35818/are-passw...
Thank you.
https://1password.community/discussion/63045/moving-beyond-1...
If stores all the passwords in encrypted js files, which the 1password.html would read in and allow for totally offline password access.
> Before we jump in, I wanted to share some history with you. Back in 2009 when we first built 1PasswordAnywhere, it wasn’t possible to use it with Dropbox. We couldn’t use Dropbox at the time because each file request needed to include a revision number and 1PasswordAnywhere had no way to know which revision numbers to use.
> Roustem and I explained this problem to the Dropbox Founder Arash, and he was kind enough to add a workaround to allow us to load files directly. This was state of the art technology in 2009.
The big difference is that your project is self-contained in an HTML file, which I think is a much better design
This secret contains the recovery key for a Bitcoin wallet. Crack it and take my money!"
Love it.
Attaching a challenge made a big difference, they'd spend 5 minutes trying to crack it and, in the process, realize it is actually sound (despite the simplicity).
That being said, I think most security professionals (myself included!) aren't equipped to outright "crack" this kind of thing in just a few minutes, and most should know better than to think that their inability to do so implies soundness.
With that in mind, here are some things I noticed (none of which represent an immediate break!)
* You're using SHA-1 in your KDF. That's probably fine since PBKDF2 doesn't rely on the properties of SHA-1 that have been broken, but the Web Crypto API gives you better alternatives. You could switch it out for SHA2-256 here without any breakage to the rest of the scheme.
* I'm not a JS expert, but I _think_ your encryption page might allow a confused user to reuse an IV[2]. Normally this wouldn't happen because the user would refresh or reload and trigger the `init` on page load, but it would probably be better to generate the IV on demand rather than having it wait in an HTML attribute.
Again, very cool work! The fact that people can make these kinds of self-containing encrypted applications with Web APIs is a serious testament to how far the standards have progressed.
[1]: https://github.com/mprimi/portable-secret/blob/3b22d2b42baf8...
[2]: https://github.com/mprimi/portable-secret/blob/4de5e958fe6f8...
> most security professionals (myself included!) aren't equipped to outright "crack" this kind of thing in just a few minutes
When I say 'crack' in this context, I mean review the scheme and point out any obvious flaws, like you just did!
> SHA-1 -> SHA2-256
I should do this!
> reuse an IV
Indeed (there is a fine-print in the creator page that says "don't reuse across messages", but I should just regenerate proactively)
Thank you very much for the great comment!
FWIW, it's a simple composition of complex things. Still really cool, thanks for the idea!
(People are busy, attention is scarce, etc)
This secret image contains a Bitcoin wallet recovery key
If you can crack the secret, the funds are yours!
You can check the status of the wallet here:
https://www.blockchain.com/explorer/addresses/btc/1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
Now here's the secret: 0002146273a3774b3828effff3382000someGarbageSecretThatsActuallyIs{https://youtu.be/eBGIQ7ZuuiU}EnctyptedUsingARandom4096BitStringAsPassword
Which "verifiable and public" part helped?- Anyone can point to a random link on blockchain.com
- the encrypted secret can contain anything
Thoroughly evaluating security/cryptography takes deep expertise and a lot of time. You're not going to elicit that without more money, impact/fame, or technical excellence.
- Money: The original bounty was $400. An expert can probably earn $400 an hour just to investigate something, without needing to completely break it.
- Impact/fame: Barely anyone uses this project. There are tons of other tools and services that are more widely used.
- Technical excellence: There's no evidence of anything clever or interesting.
For example, researchers around the world spend tons of effort analyzing the algorithms in the various NIST cryptography competitions. There's significant impact/fame and clear evidence of technical excellence. But if some rando offers a $10k bounty for their encryption algorithm, it's not going to get the required level of scrutiny.
Plus, the bounty is just for the encryption mechanism. With security, it's usually the other moving parts that cause issues, especially in how they interact with human behavior. Phishing works without needing to break TLS, DKIM/SPF, browser sandboxing, etc.
(I read an article ~5-10 years ago by a security/crypto researcher that said basically this, but sadly I can't find it anymore.)
I still think it's great when people build things like this and when they offer any kind of bounty. I just worry that the presence of an unclaimed bounty might mislead people into overestimating the level of security.
I'm just sharing a little hack I came up with. I hope some people add it to their toolchain (not my specific implementation, the idea in general).
And offering a bounty seemed like a fun things to do, which may also catch some shallow bugs, reward the hunter, and shame me publicly :-)
I don't think of it as PR/Ad. It's a bounty. If you put in time to find a flaw, you deserve at least that much (and I'll give you more if you help me fix it).
if using a crypto algorithm also counts as "rolling your own crypto" then what's left? just don't encrypt anything, ever, because HN says we shouldn't roll our own?
Security by obscurity is real, there's nothing secret about defining the problem space in which your attackers can search.
It is amazing what all the browser APIs enable as a target platform of its own. And the portability that the (probably-disgusting amount of lines of) code provides.
Linked your project.
Or if someone has hosted it themselves then hack that hosting provider.
Or they could do something like this: https://www.theverge.com/2018/4/24/17275982/myetherwallet-ha...
Phishing is another potential one. Browser extensions, or supply chain attack on packages they use.
In practice, when exchanging emails with my mom, I'm not concerned about it.
A sophisticated attacker has many easier ways to get into my stuff than creating a fake PortableSecret.
(more detail in a different comment: https://news.ycombinator.com/item?id=34084887)
That would be a very sophisticated attacker. So back to my original point.
Beside. The README states pretty clearly this is 'demo' tech. Learn the trick and use it on your own. Depending on my GitHub tool for your critical secrets is not a good idea.
As in, here's a link to a file, you know the password, it'll self-destruct (disappear) in 24 hours.
All I wanted to show with this project is the concept of self-contained, self-extracting, super-portable secrets.
Self Destruction, Unique link + password makes it pretty secure.
With the exception of Internal sabotage, I don't see any other issue.
From some googling, pbkdf2 increases CPU usage to make brute force harder, scrypt increases memory usage to make brute force harder. ARGON2 increases CPU and RAM usage to make brute force harder.
There are other advantages as well, and it is considered the best key derivation function right now.
Specifically, what do you mean by de-golfed (I'm only vaguely aware of what 'kids' mean by code-golf these days, and I'm kinda lost on de-golfing).
What would you like to fit into a QR code? A PortableSecret (e.g. html file)?
If you got the decryption code plus the payload small enough you could theoretically put the whole thing into a data URL (a URL that doesn't link to a remote resource, but contains all the data needed to display a web page). This data url could theoretically then be encoded into QR and accessed entirely locally on anyone's smart device.
This is how the 'secret creator' page works :-)
So yes, it would contain the PortableSecret minimized to such an extent that the whole thing fits in a QR-code (which has a practical upperlimit of a few KB?)
IDK about including a full HTML into a QR code (how would you even open it? Wouldn't a reader get confused expecting a URL or plain string?)
But...
You can publish portable secrets on your website (just make sure they aren't advertised/linked/crawled) and then create a QR code of the (secret-by-obscurity) URL.
See also the now defunct sharelock.io by Auth0: https://news.ycombinator.com/item?id=9109924
For creating and later validating magic-links (using Web APIs), I encode the IV, Salt, Cipher all in the URL as a single base64 token: https://github.com/celzero/otp/blob/cddaaa03f12f765fa8da9178...
(Btw, reading through your code makes me wonder if I should pad the plaintext to match blocksize despite https://archive.is/NX7Y2)?
(I was using AES-CBC before, that's why the padding is there)
I don't understand. Sure you sent these over an insecure channel and they end up... Being opened from a website, in a browser which downloaded JavaScript (JavaScript which may or may not be the same you downloaded yesterday when you used that same site btw)?
And we all know that browsers running unverifiable JavaScript from some Website are a... secure endpoint?
It's not a criticism: I'm probably missing something (is this something I'm supposed to run on my own server or on some computer I take offline after having opened the website from a harddisk-less system booted using a Linux Live CD?)?
How is this not something where you need to trust the website/server?
For all I know upon entering the password the secret is sent to the server over the wire.
Sure, fine, let's disconnect the computer from the Internet before entering the password...
Well then for all I know the JavaScript just downloaded may be saving the data or the secret in a cookie or whatever that is going to be read the next time the site is going to be accessed (so even opening it offline ain't sufficient: it must be done from a system which cannot persist to disk right?).
P.S: as an addition "Do you think this cannot possibly be secure? Great, prove it. This secret contains the recovery key for a Bitcoin wallet. Crack it and take my money!". I'm sorry but that's not how security works. It simply ain't. Once again: I'm probably missing something but reading this thread so far I feel I've been catapulted in an alternate reality, complete with people thinking that this message is somehow a proof that this scheme is secure (which it may or may not be, but that people cannot steal the coins ain't proving jack shit).
That's not how security works, but that's how a bounty works. If you can do ___, then you get ___. That's it.
If it's any consolation, I sent this project to (security professional) colleagues in the past to get their take on it. This is also not how security works, but to me is better than nothing.
Remember this is not a product. I don't care if you use it. I'm just sharing my hack for carrying secrets around without needing a special device or key.
Similarly, there is no magic dust in a live CD that makes you immune to security issues when running it.
The second one is that you can open the file in an editor and verify what it does before trying to decrypt.
Any modern browser also has protections that prevent a random HTML file from acting like a virus (stealing and uploading files).
I'm not sure if this is a problem, but one thing that is unclear to me is how/if this protects against an adversary that can modify the html file.
If the adversary can modify the HTML file in transit they can just add some code that sends the password to the adversary's server when the real recipient opens the file. (Of course, the recipient can run it in some air gapped browser etc, but that limits the practical use case quite a lot.)
And if you want to use this to send messages over e.g. email this seems like a somewhat important thing to protect against. I guess you could send the portable secret html file separately, and then the user copy-pastes the message in some text-box, but again this makes it more clunky.
While it's very real in theory, I am not concerned in practice.
If I am the target of a sophisticated attacker, there are easier and more effective ways to pwn me.
A few other comments reference the same, e.g.: https://news.ycombinator.com/item?id=34085245
Maybe it would be good to document this a bit more clearly that this mainly protects against weak adversaries. On the website you make some comparisons to GPG etc, which is a very different level of protection from my understanding, and may give a false sense of security.
I think I would prefer an approach where each person has their own html file, and then they can copy-paste the message into a text box and then decrypt it. Then you could also use public-key cryptography etc, and store a (encrypted) private-key in the html file itself. Like a light-weight GPG client in a single static html page. I guess the main feature that I don't see how to add is how to store and keep track of the public keys for your friends in a nice way.
See here if interested: https://github.com/mihaigalos/pass
My first reaction was "why not a password-protected zip" and you already linked to a relevant stackexchange question. I think it might be helpful to add a "Why not a password-protected zip/rar/7zip/..." on your page when you have time for it.
Or maybe even explicitly make clear which security goals (confidentiality, integrity, etc.) are satisfied by this. The reason being of course that I would like to show this to colleagues/friends and not having to debate this myself :)
Great suggestion!
> not having to debate this myself
eh eh.. good luck with that...
I think the problem is that it can be used "good" and can be used "bad". Some people focus/fixate on the ways you can shoot yourself in the foot with this. Other think of the good use cases it enables.
We still need to solve for obsolescence. You can encrypt a file today using a cypher that will eventually be removed from all browsers, desktops, and phones.
- Too old, no software can decrypt it: not worried about this. These are NIST-standard algorithms, there built-in in most programming languages, they'll be around for a while
- Too old, trivial to crack: this is a bit more concerning to me. It's possible that some entities around the world can already crack this encryption in minutes/hours days
Regarding the second, I'm already working on an Elliptic Curve version of this.
You can check server logs to see if those URLs are ever hit.
And if you ever need to, you can abandon the original link after changing what those non-published URLs point to (something "fun", like a rickroll perhaps).
In fact, how about using the Wayback Machine to store a bunch of versions of the static page, each containing different versions of the cipher text. Only you know which date range contains the proper cipher text!
As the old adage says 'any problem can be resolved by adding one more layer of indirection'.
It requires a maintenance toil task to make the occasional conversion from unsupported cyphers to supported cyphers.
Maybe the page needs a second button and JS function - re-encrypt.
If I want to run ancient app (MS-DOS or even ZX Spectrum), there are plenty of well supported modern emulators. But a 5 year browser with feature removed for security reasons like Flash? That's much harder.
Argon2 is only making itself in, phasing it out will take decades. OTOH you have a point in that the author's implementation PBKDF2 is being used, and that should already have retired a decade ago.
Some secrets don’t belong in your password manager. Things like backup private keys, 2FS recovery keys, wallet keys, safe combinations, treasure maps, etc.
I am a 1password user and am aware that I am trusting a 3rd party with most of my life basically (minus the 2FA, my phone), but that's the way I decided for convenience. But why would I keep passwords in there but not PKs, wallet keys etc.? To me they all have the same value. What am I missing?I think for an average person, the biggest factor is not the strength of the security. You’re already better than 99% of people if you use different passwords per site and store them behind a password. No hacker will spend weeks cracking your passwords if he can get the passwords of those other 99% for free.
So I’d say, pick the solution most convenient for you that is least likely to break over time. And an established name like 1Password sounds great for that.
I do use a password manager.
PortableSecret is a complement, not a replacement.
e.g. where do you store the recovery key for your password manager?
I also use this to store tax documents and other mildly secret documents which definitely don't belong in a password manager that copies to who-knows-where-and-in-how-many-copies.
The "lost thumbdrive" comment makes me wonder if a browser from 20 years (or more) in the future will still have enough legacy functionality to decrypt these payloads.
Consider a magic unpickable door lock that automatically unlocks itself at midnight. The lock has no security vulnerabilities (it's doing exactly what it's supposed to, and there's no way to subvert it), but your house probably does.
The secret/key management part is just an OOB secret, and provided it's in the form of a long passphrase, it should be sufficient, and doesn't rely on patients and regular people doing key management or maintaining keypairs. You just send them the passphrase in the physical mail or some other channel. If they lose it, you just generate another token blob with a new passphrase, etc.
That use case may be declining as privacy rules have been gutted lately, but WebCrypto could facilitate some interesting new protocols for a variety of cases.
My use-case was for traveling, it seems like a good idea to have a backup photo of my passport and credit card in case I loose everything. Sure I could put it on Dropbox, but do I really want to log in to my entire Dropbox on someone else’s machine?
Ironically, it has yet to be useful. Just a fun project inspired by the realization that you can base64 just about anything in an HTML document.
Main difference I see: you have thousands of lines of JS in your vault. Mine is a lot simpler because it uses the browser Cryptography APIs.
Linked your project from the README.
I mean, it's very cool all on it's own, and great job in building it! I'm just hopeful that someone is taking notes.
A post-it note that says “my daughter’s birthday” written on it is secure in the same context. Even if it upload a picture of said post-it note to Dropbox.
p.s. don't use password protected archives: https://security.stackexchange.com/questions/35818/are-passw...
if it could be 'tweaked' with the following suggestions - even better
- Plausible deniability built in (with one or two passwords)
- if you enter the wrong password you do not get an error message on the unencryption, but just garbage out
Very solid use case here. I installed Signal on my mom's phone, but also her phone is full of scary apps. I feel like .. let it be.
One additional feature you can add is a recovery key.
You could use a time-limited master recovery key and encrypt the file's data key and store it within the HTML file as an encrypted header.
It of course increases the attack surface because an attacker can then just focus on the recovery key.
But it would help in the scenarios where the passphrase for the datakey is forgotten and you need a way to recover. By supplying the master recovery passphrase, the file's data key/passphrase can be recovered and the content decrypted.
This is a usability versus security tradeoff.
This reminds me of LifeLock CEO's Todd Davis public challenge [1] when he revealed his Social Security number prominently on his site and billboards with overconfidence that his identity cannot be stolen but, unfortunately, he's been a victim of identity theft at least 13 times.
That said, I ask myself every day if having my public identity associated to my project, website, etc. Was a good idea.
It certainly helped with jobs in the past, but it's scary to hear stories of devs impersonated by others.
You are such a humble person as you clearly stated why this thing was built. I am, in no way, claiming that you are too confident in your work, despite it being a cool project that can be used by privacy-aware techies. Your expression Crack me if you can just triggered LifeLock's story from the deepest part of my mind.
I should really make sure IV/Salt are regenerated automatically after use. (there is a small print warning in the creator about reuse)
Apparently it was the other cofounder. I confused the two.
One way to see this is "like encrypted PDF, but for any kind of file".
Basically a simple GUI on top of PGP. No CLI headache and is completely independent of OS. Encrypted sources follow PGP protocol so are completely backward compatible with CLI tools. Also supports both text and file encryption/decryption.
PGP impl uses proton's openPgp.js
Perhaps you can add this as optional instructions to the decryption page.
i think self-extracting archives (like 7z's sfx stubs) edges this out as it's one less dependency. Could you create a self-extracting archive for multiple platforms?
How are they different? Seriously they seem to have the same features but obviously if someone else created this. The. there has to be a difference, so what is the difference between these two??
Linked your project.
Visiting the secret's page from the "recently closed" or "history" views of Brave/Chrome leaves the password in text entry box.
Edge doesn't do it.
Probably there's some easy fix for it, I'd guess, but I'm not really a web dev.
I'm also not a web dev, but I think I can manage to clear out the password once the secret is decrypted successfully.
You don't have to re-enter the key during each save, the plugin keeps the key during the vim session in an encrypted form (encrypted with a temp key).
The vim extension is using openssl for aes encryption (using aes-256-ecb - so if a part of the file gets damaged then you won't loose the whole file)
(oh, vim -x seems to be doing something similar, they use blowfish as the default. I am not hashing the text in order to verify its authenticity, probably should add that to my vim extension)
Why don't wallet keys, safe combinations and treasure maps belong in a password manager?
There's other secrets I'd rather never upload to the cloud, with all the risks that entails. I have various other methods to store and backup those secrets. This tool is part of that toolkit.
No complex, million+ SLOC codebases to install, except the one browser. I'll stick with gpg signing my pass repo and call it a day.
But I can't expect my mom or girlfriend to learn how to use it.
With PortableSecret I can communicate privately with them, without installing or learning anything new.
Firstly, the repeated Java Script delivery problem
The library that generates random numbers is bundled in your browser. However, the code that calls that library is delivered from network every time, e.g.
let iv = crypto.getRandomValues(new Uint8Array(blockSize));
This code depends on what the server yields for every connection. There is no audit trail to check how the program behaved in the past.
Secondly, passwords. When you're grandma-proofing your product, introducing a low entropy secret from which key is derived creates a weak link for the communications' key. Stretching the key with PBKDF2 doesn't really help because the initial entropy is so low.
Ideally you want very strong key stretching with memory hard hash functions like Argon2, and you'll want to target local encryption of strong random keys with the password, not the communications itself. This is why we want public key authentication for SSH server and no passwords. It's safer that the weak password stays on the user's device.
Lastly, encryption is about converting confidentiality problem into a key management problem. This application doesn't solve the key delivery problem, if exchanging a secret such as the password over e.g. a telephone line is what you need to do, you might as well use that line to exchange the super secret comms.
The author describes this as a hack, when in reality it's just a bad product that doesn't make it easy to automate best practices. I have much more trust in stuff like Signal that generates (and upgrades automatically) strong secrets, uses public key crypto, and allows authenticating key exchanges with values that are safe to say over even an eavesdropped channels.
There's even open source and reproducible builds. That stuff isn't grandma proof, but at least its researcher proof when there at least IS some audit trail.
Even if it was loading remote scripts, they could be secured by using an integrity hash (another modern browser feature).
But yeah my bad, apparently the actual problems with this tools are with usage, password hashing, and non-existent secret sharing mechanisms.
Despite your protests, for an average joe who just wants to stash a secret somewhere and not have it in plaintext, this is absolutely ok.
The threat model "for an average Joe who just wants to stash a secret somewhere and not have it in plaintext" should probably be written in red, font size 48.
But take a look what the author is actually saying it can be used for, i.e. to "securely store passwords". The currently available tools like KeepassXC that do just that, also use Argon2.
"Your Argon2 memory hard function is useful against mass surveillance and belongs in mass market products."
Well if this product isn't for mass-market, it's for niche use, and here I thought niche products are usually for the special security cases for people who need extra security, but you're implying average Joes should NOT use mass market grade security but something niche and less secure.
That said, the password strength and the strength of the side-channel to transmit it depend on your use case.
If we were friends for example, I may not need to send you a password at all. I could just add some secret questions we both know in the hint.
Or, at the opposite side of the spectrum, I could send you a secret as email attachment and *include the password in the email itself*. This adds zero security in certain scenarios, but for example it keeps Google bots out of your private correspondence. Which is all I want sometimes.
"Don't you hate passwords that need a number and symbol?"
Easy enough to transmit over the phone and definitely more difficult than the ubiquitous "Password1!" that most people I know end up using to meet password "security" requirements.
Also, phone exchange can be preferable for many people who are less tech comfortable
If they were using a stupid hash like, say, MD5 the time to brute force that would still be months on a GPU, but they are using PBKDF2/SHA-1 which is significantly more work.
In other words they're relatively easy to exchange over a phone call but still secure.
Extends OP's page to allow saving secrets for later use.
Pretty cool trick
It's a simple hack and I use it for 3-4 use cases for which no service exists.
Among other things:
- It works offline
- My mom can use it
- It works on any device (even a borrowed one or a newly formatted one)
- It can save me if *all* my devices get stolen
- It can save me if I'm stranded in a foreign country without any document or trusted devices,
- Etc.
You should probably not treat password-protected zips as secure: https://security.stackexchange.com/questions/35818/are-passw...
>Some browsers disable window.crypto on local files and non-TLS servers
which ones do that?
If you put:
<script>
window.crypto.subtle.generateKey(
{name: "ECDSA", namedCurve: "P-256"},
false, ["sign", "verify"])
.then(function(key){alert(key.publicKey)})
</script>
in a local HTML file and visit it in your browser, all four browsers alert with "[object CryptoKey]".[1] https://developer.mozilla.org/en-US/docs/Web/API/Crypto/subt...
[2] https://developer.mozilla.org/en-US/docs/Web/Security/Secure...
i.e. if you run the creator with a simple HTTP server on localhost:8080 it'll block the fetch to localhost:8080/foo
What use is the picture of your passport? It would be easy to fake.
> Safeguard Your Documents! Make two copies of all your travel documents in case of emergency. Leave one copy with a trusted friend or relative at home and carry the other separately from your original documents. To help prevent theft, do not carry your passport in your back pocket, and keep it separate from your money.
https://travel.state.gov/content/travel/en/international-tra...
Thank you for sharing!
But before you hit that limit, your browser may kill the tab because it looks like it's using too many resources. Again hardware/browser/platform specific.
All in all, I'm glad this cannot be used as-is for pirate movies. That would have kept me from releasing it.
Uh, I put everything in my Keepass safe, then write the password down in an envelope in a secure location in my house.
https://github.com/mprimi/portable-secret/blob/main/creator/...
Just combine https://github.com/mejdoubi/rainbow-table and their algorithm together. It would probably take me a few hours to put together, but for someone who is very familiar with cryptography, it would be minimal work.
WebAuthn also only works in secure contexts (HTTPS)—you couldn't make it work in a plain .html file.
password protected zip files are portable too.
https://security.stackexchange.com/questions/35818/are-passw...
> Choosing a strong-enough password is key (pun intended).
> Eventually I’ll fill in this paragraph. For now all you get is the obligatory XKCD: correct-horse-battery-staple
Might as well have a password generator in the tool itself.