mprimi / portable-secret

Better privacy without special software

Home Page:https://mprimi.github.io/portable-secret/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Suggestions] “Prior Art” ⇒ 2 suggestions

smondet opened this issue · comments

https://gitlab.com/smondet/hscrypt (Uses gpg for encryption and OpenPGP.js for decryption)

2 things that is has that are nice and could be suggestions:

  1. little shell script to generate the secret html pages from the command line
  2. the decryption attempts to grab the password from the URL selector (a.k.a. the #… part, which the browser should never send to the server), you can pass document + password, over encrypted chat like Signal or Matrix.org for instance like this https://smondet.gitlab.io/hscrypt/hscrypt-test.html#test-pass-phrase.

https://gitlab.com/smondet/hscrypt

Cool! Added you to the README

the #… part, which the browser should never send to the server

Ah, very interesting bit of the spec I wasn't aware of!

Thank you for the suggestions!
I've been tempted by a CLI generator as you suggested, but I can't expect my mom to learn how to use it ("easy enough for my mom to use" was one of my criteria for this project).

@smondet introduced me to hscrypt a few years back, and I riffed on it a bit at https://github.com/hscrypt:

@robinmoisson's staticrypt is also interesting "prior art"!


Pretty tangential, but two avenues for further work I've been thinking about:

<Encrypted> React component

I'm still pretty interested in streamlining the DX around creating the plaintext and ciphertext sites, and letting them be fully functional web apps. I often have notebooks or visualizations with sensitive data that I'd like to share on an "anyone with the link can view" basis. @smondet's "password in the URL fragment" trick solves part of that, but integrating the site construction with common web-dev workflows seems useful, and I haven't seen it done.

To that end, I've been thinking about whether one could make a React component that encrypts part of a page, so that the un-decrypted landing page can have nice chrome and a familiar-looking "login" flow (though it would only accept a password, not a username).

Next.js has various hooks for rendering things differently on client and server, so I've been thinking about whether an interface like this is possible:

function MyApp() {
    return <Layout>
        <Nav  />
        <Encrypted pswd={window.pswd} /* only set on server…? */ >
            <table> {/* secret data! */} </table>
            <Plot /* secret plots! */ />
        </Encrypted>
    </Layout>
}

Encrypting just data, not markup

In some cases, the components / HTML structure don't even need to be a secret, just the data; that may be even easier to support:

function MyApp({ encryptedData }) {
    const [ decryptedData, setDecryptedData ] = useState(null)
    return <Layout>
        <Nav  />
        <DecryptionForm encryptedData={encryptedData} onDecrypt={setDecryptedData} />
        {decryptedData && <Plot data={decryptedData} />}
    </Layout>
}

In this case encryptedData would be generated out-of-band, using a CLI like hscrypt's that Seb mentioned above, so I guess this flow is pretty possible today. It would be cool to offer a helper for doing it in next.js' getStaticProps hook for a given page (which runs only server-side / at site-generation time):

export function getStaticProps() {
    // Load secretData.json
    const secretData = JSON.parse(fs.readFileSync("secretData.json", "utf-8"))
    // Encrypt with the current Git SHA
    const encryptionKey = require('child_process').execSync('git log -1 --format=%H', { encoding: 'utf-8' }).trim()
    const encryptedData = encrypt(secretData, encryptionKey)
    // Pass to page as `props`
    return { props: { encryptedData } }
}
export default function MyApp({ encryptedData }) {
    // same as previous `MyApp`
}

Then next build && next export would be pretty CI/CD-ready…

GitHub Action

A lot of my use cases would get published via GitHub Actions (e.g. from a private repo containing private data), so the encryption key could be a repo-level secret, or even derived from the commit SHA.

You could imagine a reusable GHA that would enable this kind of CI/CD:

on:
  push:
    branches:
      - www
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
      - run: npm install && npm run build
      - uses: mprimi/build-encrypted-static-site@v1
        with:
          src: <output dir from `npm run build` above>
          dst: encrypted-build
      - uses: JamesIves/github-pages-deploy-action@4.1.1
        with:
          folder: encrypted-build

Anyway, cool project, thanks for making it!

@ryan-williams Interesting ideas!