-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update IPFS codec registration example #20
Open
jbouwman
wants to merge
3
commits into
ceramicnetwork:main
Choose a base branch
from
jbouwman:ipfs-codec-doc-update
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -105,16 +105,15 @@ const payloadBlock = await Block.create({ bytes: payloadBytes, cid: payloadCid, | |||||
|
||||||
## JWE Encryption Usage | ||||||
|
||||||
When using DAG-JOSE (for JWE or JWS) with js-IPFS, you will need to convert it from a raw multiformats style codec to a legacy IPLD codec using [blockcodec-to-ipld-format](https://github.com/ipld/js-blockcodec-to-ipld-format). | ||||||
When using DAG-JOSE (for JWE or JWS) with js-IPFS, you will need to register the codec when creating the IPFS instance. For versions of js-IPFS older than 0.41, it is also necessary to a convert it from a raw multiformats style codec to a legacy IPLD codec using [blockcodec-to-ipld-format](https://github.com/ipld/js-blockcodec-to-ipld-format). | ||||||
|
||||||
_The following example is available in complete form in [example-ipfs.mjs](./example-ipfs.mjs)._ | ||||||
_The following example is available in complete form in [example-ipfs.mjs](./example-ipfs.mjs). An example of legacy IPLD codec registration at [example-ipfs-legacy.mjs](./example-ipfs-legacy.mjs)._ | ||||||
|
||||||
_A plain IPLD (without IPFS, for cases where you are managing the block store) version is available in [example-ipld.mjs](./example-ipld.mjs)._ | ||||||
|
||||||
```js | ||||||
// IPLD & IPFS | ||||||
import { create as createIpfs } from 'ipfs' | ||||||
import { convert as toLegacyIpld } from 'blockcodec-to-ipld-format' | ||||||
|
||||||
import * as dagJose from 'dag-jose' | ||||||
``` | ||||||
|
@@ -144,13 +143,11 @@ import { generateKeyPairFromSeed } from '@stablelib/x25519' | |||||
Set up js-IPFS: | ||||||
|
||||||
```js | ||||||
const dagJoseIpldFormat = toLegacyIpld(dagJose) | ||||||
|
||||||
// Async setup tasks | ||||||
async function setup () { | ||||||
console.log('Starting IPFS ...') | ||||||
// Instantiate an IPFS node, that knows how to deal with DAG-JOSE blocks | ||||||
ipfs = await createIpfs({ ipld: { formats: [dagJoseIpldFormat] } }) | ||||||
ipfs = await createIpfs({ ipld: { codecs: [dagJose] } }) | ||||||
} | ||||||
``` | ||||||
|
||||||
|
@@ -166,7 +163,7 @@ const storeEncrypted = async (payload, key) => { | |||||
// encrypt into JWE container layout using secret key | ||||||
const jwe = await createJWE(cleartext, [dirEncrypter]) | ||||||
// let IPFS store the bytes using the DAG-JOSE codec and return a CID | ||||||
const cid = await ipfs.dag.put(jwe, { format: dagJoseIpldFormat.codec, hashAlg: 'sha2-256' }) | ||||||
const cid = await ipfs.dag.put(jwe, { format: 'dag-jose', hashAlg: 'sha2-256' }) | ||||||
console.log(`Encrypted block CID: \u001b[32m${cid}\u001b[39m`) | ||||||
return cid | ||||||
} | ||||||
|
@@ -206,7 +203,7 @@ const storeEncrypted = async (payload, pubkey) => { | |||||
// encrypt into JWE container layout using public key | ||||||
const jwe = await createJWE(cleartext, [asymEncrypter]) | ||||||
// let IPFS store the bytes using the DAG-JOSE codec and return a CID | ||||||
const cid = await ipfs.dag.put(jwe, { format: dagJoseIpldFormat.codec, hashAlg: 'sha2-256' }) | ||||||
const cid = await ipfs.dag.put(jwe, { format: 'dag-jose', hashAlg: 'sha2-256' }) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
console.log(`Encrypted block CID: \u001b[32m${cid}\u001b[39m`) | ||||||
return cid | ||||||
} | ||||||
|
@@ -246,7 +243,7 @@ const cleartext = prepareCleartext({ my: 'secret message' }) | |||||
|
||||||
// encrypt and put into ipfs | ||||||
const jwe = jose.JWE.encrypt.flattened(cleartext, jwk, { alg: 'dir', enc: 'A128CBC-HS256' }) | ||||||
const cid = await ipfs.dag.put(jwe, { format: format.codec, hashAlg: 'sha2-256' }) | ||||||
const cid = await ipfs.dag.put(jwe, { format: 'dag-jose', hashAlg: 'sha2-256' }) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
// retreive and decrypt object | ||||||
const retrived = await ipfs.dag.get(cid) | ||||||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { randomBytes } from '@stablelib/random' | ||
import { generateKeyPairFromSeed } from '@stablelib/x25519' | ||
|
||
// IPLD & IPFS | ||
import { create as createIpfs } from 'ipfs' | ||
import { convert as toLegacyIpld } from 'blockcodec-to-ipld-format' | ||
|
||
// JWT & utilities | ||
import { | ||
xc20pDirEncrypter, | ||
xc20pDirDecrypter, | ||
x25519Encrypter, | ||
x25519Decrypter, | ||
decryptJWE, | ||
createJWE | ||
} from 'did-jwt' | ||
import { | ||
decodeCleartext, | ||
prepareCleartext | ||
} from 'dag-jose-utils' | ||
|
||
import * as dagJose from './lib/index.js' | ||
|
||
// Translate DAG-JOSE into the IPLD interface js-IPFS understands | ||
const dagJoseIpldFormat = toLegacyIpld(dagJose) | ||
let ipfs | ||
|
||
// Async setup tasks | ||
async function setup () { | ||
console.log('Starting IPFS ...') | ||
// Instantiate an IPFS node, that knows how to deal with DAG-JOSE blocks | ||
ipfs = await createIpfs({ ipld: { formats: [dagJoseIpldFormat] } }) | ||
} | ||
|
||
async function symmetric () { | ||
// Encrypt and store a payload using a secret key | ||
const storeEncrypted = async (payload, key) => { | ||
const dirEncrypter = xc20pDirEncrypter(key) | ||
// prepares a cleartext object to be encrypted in a JWE | ||
const cleartext = await prepareCleartext(payload) | ||
// encrypt into JWE container layout using secret key | ||
const jwe = await createJWE(cleartext, [dirEncrypter]) | ||
// let IPFS store the bytes using the DAG-JOSE codec and return a CID | ||
const cid = await ipfs.dag.put(jwe, { format: dagJoseIpldFormat.codec, hashAlg: 'sha2-256' }) | ||
console.log(`Encrypted block CID: \u001b[32m${cid}\u001b[39m`) | ||
return cid | ||
} | ||
|
||
// Load an encrypted block from a CID and decrypt the payload using a secret key | ||
const loadEncrypted = async (cid, key) => { | ||
const dirDecrypter = xc20pDirDecrypter(key) | ||
const retrieved = await ipfs.dag.get(cid) | ||
const decryptedData = await decryptJWE(retrieved.value, dirDecrypter) | ||
return decodeCleartext(decryptedData) | ||
} | ||
|
||
const key = randomBytes(32) | ||
const secretz = { my: 'secret message' } | ||
console.log('Encrypting and storing secret:\u001b[1m', secretz, '\u001b[22m') | ||
const cid = await storeEncrypted(secretz, key) | ||
const decoded = await loadEncrypted(cid, key) | ||
console.log('Loaded and decrypted block content:\u001b[1m', decoded, '\u001b[22m') | ||
} | ||
|
||
// Asymmetric encryption using a private and public key | ||
async function asymmetric () { | ||
// Encrypt and store a payload using a public key | ||
const storeEncrypted = async (payload, pubkey) => { | ||
const asymEncrypter = x25519Encrypter(pubkey) | ||
// prepares a cleartext object to be encrypted in a JWE | ||
const cleartext = await prepareCleartext(payload) | ||
// encrypt into JWE container layout using public key | ||
const jwe = await createJWE(cleartext, [asymEncrypter]) | ||
// let IPFS store the bytes using the DAG-JOSE codec and return a CID | ||
const cid = await ipfs.dag.put(jwe, { format: dagJoseIpldFormat.codec, hashAlg: 'sha2-256' }) | ||
console.log(`Encrypted block CID: \u001b[32m${cid}\u001b[39m`) | ||
return cid | ||
} | ||
|
||
// Load an encrypted block from a CID and decrypt the payload using a secret key | ||
const loadEncrypted = async (cid, privkey) => { | ||
const asymDecrypter = x25519Decrypter(privkey) | ||
// decode the DAG-JOSE envelope | ||
const retrieved = await ipfs.dag.get(cid) | ||
const decryptedData = await decryptJWE(retrieved.value, asymDecrypter) | ||
return decodeCleartext(decryptedData) | ||
} | ||
|
||
const privkey = randomBytes(32) | ||
// generate a public key from the existing private key | ||
const pubkey = generateKeyPairFromSeed(privkey).publicKey | ||
const secretz = { my: 'secret message' } | ||
console.log('Encrypting and storing secret with public key:\u001b[1m', secretz, '\u001b[22m') | ||
const cid = await storeEncrypted(secretz, pubkey) | ||
const decoded = await loadEncrypted(cid, privkey) | ||
console.log('Loaded and decrypted block content with private key:\u001b[1m', decoded, '\u001b[22m') | ||
} | ||
|
||
// Run! | ||
setup().then(() => { | ||
console.log('Running symmetric example...') | ||
symmetric().then(async () => { | ||
console.log('Running asymmetric example...') | ||
await asymmetric() | ||
process.exit(0) | ||
}) | ||
}).catch((e) => { | ||
console.error(e.stack) | ||
process.exit(1) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
best to use use
dagJose.name
since that's the internal matching that's going to happen in js-ipfs and the user can avoid one magic stringThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.