Skip to content

Instantly share code, notes, and snippets.

@smcatala
Last active November 30, 2016 10:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smcatala/bee0f411b08ec45933cb69264812a62e to your computer and use it in GitHub Desktop.
Save smcatala/bee0f411b08ec45933cb69264812a62e to your computer and use it in GitHub Desktop.
easily run opgp-service in a web-worker with worker-proxy
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1
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
mN7gO16/RLWq8LQMYpsJ
=Rm/S
-----END PGP PRIVATE KEY BLOCK-----
/**
* Copyright 2016 Stephane M. Catala
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* Limitations under the License.
*/
;
import worker = require('./worker')
import newServiceProxy, { ServiceProxy } from 'worker-proxy/dist/proxy'
import { OpgpService } from 'opgp-service' // only import the interface for casting
import * as Promise from 'bluebird'
import fs = require('fs')
const log = console.log.bind(console)
const service = newServiceProxy<OpgpService>(worker).service
const armor = fs.readFileSync(`${__dirname}/<john.doe@example.com>.private.key`, 'utf8')
const passphrase = 'passphrase to decrypt private key'
const secret = 'rob says wow!'
log('import key...')
const key = service
.call('getKeysFromArmor', armor)
.tap(() => log('key successfully imported!\nnow unlock key...'))
const unlocked = Promise.join(service, key)
.then(([ service, key ]) => service.unlock(key, passphrase))
.tap(() => log(`key successfully unlocked!\nnow encrypt then decrypt '${secret}'...`))
// encrypt with public key, sign with private
const cipher = Promise.join(service, unlocked)
.then(([ service, key ]) => service.encrypt({ cipher: key, auth: key }, secret))
.tap(log) // '-----BEGIN PGP MESSAGE----- ... -----END PGP MESSAGE-----'
// decrypt with decrypted private key, verify signature with public
const plain = Promise.join(service, unlocked, cipher)
.then(([ service, key, cipher ]) => service.decrypt({ cipher: key, auth: key }, cipher))
.tap(log) // 'rob says wow!'
.catch(log)
{
"compileOnSave": true,
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"lib": [
"es2015",
"webworker"
],
"sourceMap": true,
"noEmitHelpers": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}
/*
* Copyright 2016 Stephane M. Catala
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* Limitations under the License.
*/
;
import hookService from 'worker-proxy/dist/worker'
import newOpgpService from 'opgp-service'
export = function (self: WorkerGlobalScope) {
(<any>self).window = self // required otherwise openpgp incorrectly detects node environment!
const service = newOpgpService(/* add config object here if required */)
hookService({
worker: self,
service: service
})
}
@smcatala
Copy link
Author

smcatala commented Nov 24, 2016

this gist demonstrates how the example from opgp-service may be easily adapted to run the opgp-service in a web worker using worker-proxy:

  • in the main index.ts file, run and proxy opgp-service in a web worker with newServiceProxy<OpgpService>(require('./worker')),
  • add the worker.ts file which instantiates and hooks up opgp-service in the web worker so it can be proxied from the main thread.

bundle with browserify index.ts -p [ tsify --project . ] -t brfs -o index.js.

@smcatala
Copy link
Author

smcatala commented Nov 24, 2016

note that although openpgp-js supports running in a web worker on all evergreen browsers, the above implementation currently does not support the EDGE browser.
if you are interested in EDGE compatibility, please vote to support the Web Crypto API inside a Web Worker on EDGE.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment