The first few times I shared this with (security professional) colleagues and friends, they'd dismiss it right away "this can't possibly work", but it was because they _assumed_ it didn't work (too simple).
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).
I think this is very cool, and from a cursory look you've made most of the right design choices (to the extent that the Web Crypto API allows).
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.
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).
I hate that I’m saying this because I believe all of cryptocurrency to be a pyramid scheme, but… this is the perfect use case for a smart contract on ethereum…
why would a smart contract help though? there needs to be proof that the encrypted key is valid, this would require zero knowledge proof but I'm not sure how you can do it for this use case.
He could post a secret in the decrypted text on the page that, once submitted to the chain, fulfills the contract and transfers the ETH. I know very little about smart contracts but I thought this is what they’re good at… “if a value is posted with a sha512 hash that matches x, the contract is fulfilled”, and put the value on the page, encrypted, and ask hackers to decrypt it.
It doesn’t necessarily prove that the encrypted key is valid, but it proves that the author put some money up on the chain at least. It could always be that the decrypted text doesn’t provide the key that fulfills the contract, but ultimately that isn’t a solvable problem. You can’t prove a claim about some encrypted text without someone having the ability to decrypt it.
But then you don’t need to have a smart contract, simply posting public key of the wallet is enough (to verify the content of the wallet). The contract at most provides an escrow, but even that isn’t really the case since presumably the originator has the key to pull the money (since he knows the secret key).
Proving that an encrypted text has the private key is possible for some encryption schemes through zero knowledge proofs, but I guess not in this case in particular.
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
They didn't do it here, but you can sign a message that includes a checksum of the application with the private key of that address. The signed message can be proved using just the public key that they have linked to.
this doesn't, it uses the browser's builtin Web Cryptography API.
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?
Yes, using a crypto algorithm also counts as rolling your own crypto. You're putting together crypto libs that others wrote. Most crypto vulnerabilities come from glueing together solid crypto implementations. The glueing has to be solid too. Just "using" a crypto algorithm sounds like a recipe for a vulnerability.
I'm not a crypto expert, I'm just telling you what I've been reading on HN for the past few years.
Using the output of a language model like mine as a comment reply on a forum like HN could potentially have a negative impact on the discourse in a number of ways.
1. It could undermine the authenticity and integrity of the conversation by introducing responses that are not genuinely from a human.
2. It could create confusion or misunderstanding, as the responses generated by the language model may not be relevant or appropriate for the specific context in which they are used.
3. It could discourage genuine participation and contribution from other members of the community, as it may seem like the conversation is being dominated by automated responses rather than authentic human interaction.
Overall, it is important to consider the impact of your actions on the online community and to strive to contribute to respectful and meaningful discourse. Using the output of a language model as a substitute for genuine human interaction is generally not a good idea, as it can undermine the authenticity and integrity of the conversation.
You're not completely wrong in that it's still possible to f up, even when using misuse resistant primitives.
The difference is, you're sort-of allowed to f up if it's an intelligent mistake that teaches the creators of misuse resistant libraries a thing or two about where they went wrong. If OTOH you're clearly just yoloing it, introducing your pseudo-math BS into the mix, or intentionally deviating from best practices or breaking it, then it's on you.
Notice they have also given clues to what the password words are. So with brute force, maybe spending a good portion of the bounty on cloud resources, you might crack it that way :-)
Offering a bounty like this has value, but probably only for finding shallow bugs.
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 built a similar tool after Firefox send got killed. It was only for transient messages (e.g. sending secrets to someone else or an other device). I don’t know that I love the idea of these being long-lived, as I’m not sure I trust my password abilities.
Not the original commenter, but if the whole HTML could be included, it would be nice. It is defenitely possible until certain data limits. However, you would need certain app to use it, since by default QR readers probably can’t benefit from it so that it actually increases the usability. File should be extracted and then opened with browser from correct path.
Code golfing is the act of finding ever and ever smaller, but functionally equivalent, expressions of a specific piece of code. Usually involves a lot of tricks specific to the language the golfing is done in.
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.
Like sibling comment elucidates, code-golfing is just using tricks to get the size of a program down without impacting its functionality. This could be as simple as using single-character variable names or something more complicated like including a decompressor that expands some packed code before execution.
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.
Minification may, or may not, involve munging, for example shortening `const foobar = 1;` into `var f = 1;`. This is not always a safe operation, and in some cases you want to disable munging when minifying your code so that you have meaningful component / function names in your stack traces even without sourcemaps.
> 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)
If that wasn't the case, then "HTML virus" would be a thing:
I send you an HTML file and, if you open it, it read files from your hard drive and uploads them to my server.
It's been a while and I don't remember the details.
All I remember is that I was developing the secret 'creator' code using Brave (my default unsecured browser) and at some point I had to switch to Safari (which I normally save for trusted websites only).
It's possible it was a red herring, and I switched browser but the problem was something else I did at the same time.
I should have clarified - I mean I was wondering if any browsers block fetch to remote URLs from local files
I do vaguely recall encountering some problem I didn't expect when I was making a tool contained in a local html file, but I dont remember which browser I was using at the time
It is documented [1] as only being available in secure contexts, which is normally https:// but does include file:// urls. Testing now, it works for me in Chrome, Safari, Brave, and Firefox.
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.
I doubt that would work. You can’t decrypt things encrypted 20 years ago on modern API’s because those algorithms are known to be insecure. You’d have to probably rewrite it from scratch or install an old version of the browser. So it’s probably best to keep a windows version of the browser since that’s currently the only OS that can run software from 20 years ago, so hopefully they’ll still be able to do that 20 years from now.
The cryptography is insecure. The code often is secure – it's just doing an insecure thing. In this example, the encrypted data is (perhaps) insecure, because the cryptography algorithm has known exploits.
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.
I assumed you meant something slightly different to what you wrote, because you wrote:
> You can’t decrypt things encrypted 20 years ago on modern API’s because those algorithms are known to be insecure.
Python's standard library, C's standard library, and Win32's CryptoAPI all beg to differ. The specific algorithms used by Crypto.subtle (Rijndael, Rivest–Shamir–Adleman) are over 20 years old, already, so even that's a counterexample.
> So it’s probably best to keep a windows version of the browser since that’s currently the only OS that can run software from 20 years ago, so hopefully they’ll still be able to do that 20 years from now.
Most operating systems can run software from 20 years ago. I'm currently running a 35-year-old piece of software on the latest version of an OS that isn't Windows. (I'm not aware of modern Windows being able to do that, actually; not since NTVDM got removed.)
Much! I'd say that there is always a counter-example. However, even RSA was generally recommended as "insecure" because people can't bother to do any research into the correct values of the parameters. The algorithm itself is secure, but most libraries didn't have sane/secure defaults until like 10ish years ago.
That was the point I was trying to make, you're making a bet that what we know today will still be true 20 years from now. The algorithms you mentioned are symmetric, IIRC, and basically any symmetric algorithm is secure as long as you have a one-time-pad or don't know any of the cleartext. That is, until someone finds a flaw with it.
I remember working on my first 'ciphersaber[1]' when it was discovered it was insecure.
> Most operating systems can run software from 20 years ago.
I was mostly referring to main-stream OS's. Linux and OSX, for example, cannot run software compiled 20 years ago (I'd love to be proven wrong, but my experience hasn't been so great!). On my modern Windows 11 PC, I can still run my first game engine demo, written and compiled in 1998 (I've since lost the source code). Or via WINE on my Linux PC, probably.
I'm sure there are niche cases out there, but the vast majority of people don't have access to those systems and OS's, while anyone can (currently) run a basic version of Windows for free.
> Linux and OSX, for example, cannot run software compiled 20 years ago (I'd love to be proven wrong, but my experience hasn't been so great!).
Just get the copy of libc it was compiled for (and any other libraries), and add them to LD_LIBRARY_PATH before running the program. Linux's ABI is stable, so this should work fine. (It's always worked for me – though I haven't tried terribly much software, I'll admit.)
I don't know about macOS; iOS has compatibility problems, but Android basically doesn't.
This is password protected, so then an attacker must crack the password. The author exchanges the password over a phone call, which requires the password to be relatively weak, meaning the password is probably crackable.
Exchanging the password via a second channel that the other user can copy and paste a more difficult password from to decyrpt the document might be more secure. The password may be more exposed, but an attacker would have to compromise both channels. Basically use two messaging platforms (one of which could be email) ideally where at least one channel is sent encrypted. For example if the other party is using their mobile phone to view the payload they should have a messaging app to copy and paste from that is at least encrypted in transit if not e2e.
This is not meant as a solution. It's a demo of a self-contained, self-extracting, portable encrypted file.
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.
Challenge: make it possible to use something like Diffie Hellman[0] to exchange a key securely even over an unsecure channel but where they resulting key is actually the password to type in and "reads" like https://xkcd.com/936/ i.e. something my grandma could type in. Without reducing the key space too much to be insecure ;)
The author recommends the use of XKCD correct-horse-battery-staple style passwords (aka diceware), which have a high ratio of entropy to ease of transmission effort.
In other words they're relatively easy to exchange over a phone call but still secure.
It does not mean the password needs to be weak at all. Make it a full sentence with punctuation, like:
"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
Passwords being transmitted over a voice call does not equate to a weak password. You can very easily communicate 4-6 English words outside the 10,000 most common to produce a password with 49-83 bits of entropy. And most people will have just as easy a time remembering 5 words as 5 alphanumerics, if not easier.
There is nothing requiring the password to be “weak”. It can be a strong password generated with a random number/strong password generator. Sharing a string of characters or a “weak phrase” is no different if reading it to the person.
28 words would be about 200 characters, though, and I don't think simply existing somewhere in plaintext is enough -- what if I said it is the first 28,000 words of the Latin Bible -- would you still consider that a weak password because it exists in plain text somewhere?
I took a list of "2000 most common English words" used metaphopne to eliminate words that sound similar to other words on the list, and reduced it to a power of 2. I ended up with 512 words that are probably in all fluent English speakers vocabularies so can easily be read over the phone. It's 9 bits per word, so 7 words is 63 bits of entropy which means it's (on average) 2^62 times more computational work to brute-force than it is do decrypt. That's a pretty good margin to have.
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.
The bounty password looks like 2 names, a type of flower, and a two word object. That significantly reduces the search space. Though, it's likely at least one of those words are non-standard or wouldn't be found in any wordlist.
This is the kind of password I use to protect my actual secrets. So if someone is able to crack it, I'd like to know. The bounty is for a 'realistic' use case.
If you want to avoid wordlist vulnerabilities, try this:
Choose a lyric from a favorite song. Concatenate the first letter of each word in the lyric. Example:
“Rock the Casbah
Sharif don't like it”
Becomes:
rtcsdli
Add capitalization or numbers/special characters according to your own pref. For example, maybe your decide to alternate lower and upper case and always end with a bang:
rTcSdLi!
Although you have to use the same capitalization rules for all passwords if you have any hope of remembering them.
That is security by obscurity. If somebody knows your method, they can scrape the lyrics for all popular songs, narrow your password down to a few million possible passwords and just try them all.
10s of thousands of popular songs, dozens of lines per song.
> Although you have to use the same capitalization rules for all passwords if you have any hope of remembering them.
So no additional combinations from that. Your algorithm is simple and common enough that it's possible that an attacker can figure it out from a single leaked password. With one leaked password they've compromised all of your passwords to anything they have the capability of trying a few million passwords on.
You wrote Pooh songs. Not me. There are millions of songs with lyrics. Billions of lines of lyrics. Trillions of combinations that include upper and lower case. Good luck.
It looks like it uses a randomly generated unique 128bit salt from crypto.getRandomValues, can you explain what it is doing wrong to be rainbow attack resistant?
Yeah, plus they even give hints to the password complexity, so unless that is a red herring, this should be pretty simple to crack, if not CPU consuming.
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.
I think the author of that repo misunderstands what a rainbow table is. I only quickly skimmed the code, but it doesn't seem to do anything related to rainbow tables.
On top of that, a rainbow table (if that is what you're looking to use) would not help here. The password is both very long and salted.
The repo was just a quick example of how one would use a rainbow table to crack the password. Yes, the fact that it only generates a simple rainbow table means that it isn't the holy grail to the exercise, but the idea of a rainbow table is that someones out there have already been running and generating a rainbow table for many years.
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.
This is incredibly cool! Nice demo of a modern browser API I was not aware of, and it's actually useful. I can imagine using this to email confidential PDFs and other small deliverables for clients.
Cyphers, the algorithms used to encrypt the secret file, become obsolete over time.
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.
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.
- 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.
Well, your cipher text could decrypt to a non-published URL that has some cipher text which decrypts to another non-published URL (as many layers of indirection that you need), with the final non-published URL containing the actual cipher text you wanted to decrypt.
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!
I'd argue this isn't a cryptography problem, or at least not a purely cypto problem. Because we have the exact same issues with almost all file formats and storage mediums.
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.
XChaCha20-Poly1305 will probably never go out of fashion.
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.
The argument your answer makes discusses confidentiality issues with passwords in Zip-files, yet the Portable Secret application doesn't take any major steps or use best practices like Argon2 to solve "brute forcing the password" problem.
I wrote a similar software for the same reasons. One goal for mine was that the generated output is small enough to quickly verify that the code sent to the browser is the one you expect. Total code size is under 100 lines.
I made something similar a few years back when I was learning web dev. It's not nearly as polished, but I'd love to pick apart your code and see what design decisions we did similarly/differently
Sure, that's clear. Mine was an appreciation comment, but all the comments stating all the potential issues don't get that you're not proposing it to the government.
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?
Works pretty well on Android! Unfortunately, today I learned that FireFox doesn't seems to support opening html files. When I download the html file FF isn't one of the options to open it. Only Chrome. Anyone know an way around this?
384 comments
[ 3.7 ms ] story [ 330 ms ] threadThis 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).
FWIW, it's a simple composition of complex things. Still really cool, thanks for the idea!
(People are busy, attention is scarce, etc)
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!
[1] https://mprimi.github.io/portable-secret/examples/bounty.htm...
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).
(Now I gotta go wash my hands after typing this.)
It doesn’t necessarily prove that the encrypted key is valid, but it proves that the author put some money up on the chain at least. It could always be that the decrypted text doesn’t provide the key that fulfills the contract, but ultimately that isn’t a solvable problem. You can’t prove a claim about some encrypted text without someone having the ability to decrypt it.
Proving that an encrypted text has the private key is possible for some encryption schemes through zero knowledge proofs, but I guess not in this case in particular.
- Anyone can point to a random link on blockchain.com
- the encrypted secret can contain anything
Security by obscurity is real, there's nothing secret about defining the problem space in which your attackers can search.
This is what the bounty is for. I just hope whoever cracks it lets me know how they did it and how hard it was.
This is what a bounty is, no?
It's a cute marketing gimmick, that's about 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?
I'm not a crypto expert, I'm just telling you what I've been reading on HN for the past few years.
1. It could undermine the authenticity and integrity of the conversation by introducing responses that are not genuinely from a human.
2. It could create confusion or misunderstanding, as the responses generated by the language model may not be relevant or appropriate for the specific context in which they are used.
3. It could discourage genuine participation and contribution from other members of the community, as it may seem like the conversation is being dominated by automated responses rather than authentic human interaction.
Overall, it is important to consider the impact of your actions on the online community and to strive to contribute to respectful and meaningful discourse. Using the output of a language model as a substitute for genuine human interaction is generally not a good idea, as it can undermine the authenticity and integrity of the conversation.
The difference is, you're sort-of allowed to f up if it's an intelligent mistake that teaches the creators of misuse resistant libraries a thing or two about where they went wrong. If OTOH you're clearly just yoloing it, introducing your pseudo-math BS into the mix, or intentionally deviating from best practices or breaking it, then it's on you.
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 :-)
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)?
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.
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 :-)
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)
>Some browsers disable window.crypto on local files and non-TLS servers
which ones do that?
i.e. if you run the creator with a simple HTTP server on localhost:8080 it'll block the fetch to localhost:8080/foo
If that wasn't the case, then "HTML virus" would be a thing: I send you an HTML file and, if you open it, it read files from your hard drive and uploads them to my server.
I'm pretty sure Brave was blocking window.crypto but can't remember if it was on a file or over plain HTTP
Blocking crypto on file:// is not to spec, and testing above (https://news.ycombinator.com/item?id=34084526) none of the browsers do that.
All I remember is that I was developing the secret 'creator' code using Brave (my default unsecured browser) and at some point I had to switch to Safari (which I normally save for trusted websites only).
It's possible it was a red herring, and I switched browser but the problem was something else I did at the same time.
I do vaguely recall encountering some problem I didn't expect when I was making a tool contained in a local html file, but I dont remember which browser I was using at the time
If you put:
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...
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.
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.
> You can’t decrypt things encrypted 20 years ago on modern API’s because those algorithms are known to be insecure.
Python's standard library, C's standard library, and Win32's CryptoAPI all beg to differ. The specific algorithms used by Crypto.subtle (Rijndael, Rivest–Shamir–Adleman) are over 20 years old, already, so even that's a counterexample.
> So it’s probably best to keep a windows version of the browser since that’s currently the only OS that can run software from 20 years ago, so hopefully they’ll still be able to do that 20 years from now.
Most operating systems can run software from 20 years ago. I'm currently running a 35-year-old piece of software on the latest version of an OS that isn't Windows. (I'm not aware of modern Windows being able to do that, actually; not since NTVDM got removed.)
Does this address your comment better?
Much! I'd say that there is always a counter-example. However, even RSA was generally recommended as "insecure" because people can't bother to do any research into the correct values of the parameters. The algorithm itself is secure, but most libraries didn't have sane/secure defaults until like 10ish years ago.
That was the point I was trying to make, you're making a bet that what we know today will still be true 20 years from now. The algorithms you mentioned are symmetric, IIRC, and basically any symmetric algorithm is secure as long as you have a one-time-pad or don't know any of the cleartext. That is, until someone finds a flaw with it.
I remember working on my first 'ciphersaber[1]' when it was discovered it was insecure.
> Most operating systems can run software from 20 years ago.
I was mostly referring to main-stream OS's. Linux and OSX, for example, cannot run software compiled 20 years ago (I'd love to be proven wrong, but my experience hasn't been so great!). On my modern Windows 11 PC, I can still run my first game engine demo, written and compiled in 1998 (I've since lost the source code). Or via WINE on my Linux PC, probably.
I'm sure there are niche cases out there, but the vast majority of people don't have access to those systems and OS's, while anyone can (currently) run a basic version of Windows for free.
[1]: http://ciphersaber.gurus.org/
Just get the copy of libc it was compiled for (and any other libraries), and add them to LD_LIBRARY_PATH before running the program. Linux's ABI is stable, so this should work fine. (It's always worked for me – though I haven't tried terribly much software, I'll admit.)
I don't know about macOS; iOS has compatibility problems, but Android basically doesn't.
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.
> I created Portable Secret to securely exchange documents via email with my mother, who can’t be expected to learn PGP, age, or similar.
[0] https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exc...
In other words they're relatively easy to exchange over a phone call but still secure.
For example, the password hint for a secret I send to my sister:
- The name of our neighbors cat
- The name of your first boyfriend who scratched dad's car
- Mom's nickname for aunt Ilda
Concatenate those three with a dot. And voila, a pretty secure password without need of a side channel.
(just made this up, I don't have a sister...)
"Live well, Laugh Often, Love Much"
"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
Psalms23:2
and have a 14 word passphrase.
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.
This is the kind of password I use to protect my actual secrets. So if someone is able to crack it, I'd like to know. The bounty is for a 'realistic' use case.
Choose a lyric from a favorite song. Concatenate the first letter of each word in the lyric. Example:
“Rock the Casbah Sharif don't like it”
Becomes:
rtcsdli
Add capitalization or numbers/special characters according to your own pref. For example, maybe your decide to alternate lower and upper case and always end with a bang:
rTcSdLi!
Although you have to use the same capitalization rules for all passwords if you have any hope of remembering them.
The combinations are easily in the trillions, likely much much more. Read the algorithm.
An algorithm for password generation is not security by obscurity.
> Although you have to use the same capitalization rules for all passwords if you have any hope of remembering them.
So no additional combinations from that. Your algorithm is simple and common enough that it's possible that an attacker can figure it out from a single leaked password. With one leaked password they've compromised all of your passwords to anything they have the capability of trying a few million passwords on.
https://www.youtube.com/watch?v=xLd22ha_-VU
Or 24h, flight tickets, and a wrench.
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.
What amount of money would make you actually try to crack it?
On top of that, a rainbow table (if that is what you're looking to use) would not help here. The password is both very long and salted.
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.
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.
One way to see this is "like encrypted PDF, but for any kind of file".
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.
1pass literally can solve every single one of these problems.
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.
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.
- 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.
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.
You should probably not treat password-protected zips as secure: https://security.stackexchange.com/questions/35818/are-passw...
> 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]).
[1] https://privatebin.info/
https://github.com/dividuum/html-vault
Linked your project.
https://9p4.github.io/hackna/
The big difference is that your project is self-contained in an HTML file, which I think is a much better design
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?