forked from ceramicnetwork/js-dag-jose
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample-ipld.mjs
111 lines (101 loc) · 4.36 KB
/
example-ipld.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { randomBytes } from '@stablelib/random'
import { generateKeyPairFromSeed } from '@stablelib/x25519'
// JWT & utilities
import {
xc20pDirEncrypter,
xc20pDirDecrypter,
x25519Encrypter,
x25519Decrypter,
decryptJWE,
createJWE
} from 'did-jwt'
import {
decodeCleartext,
prepareCleartext
} from 'dag-jose-utils'
import * as Block from 'multiformats/block'
import { sha256 } from 'multiformats/hashes/sha2'
import * as dagJose from './lib/index.js'
/** @type {Map<string, Uint8Array>} */
const store = new Map()
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])
// create an IPLD Block that has the CID:Bytes:Value triple
const block = await Block.encode({ value: jwe, codec: dagJose, hasher: sha256 })
console.log(`Encrypted block CID: \u001b[32m${block.cid}\u001b[39m`)
console.log('Encrypted block contents:\n', block.value)
// store the block, this could be in IPFS or any other CID:Bytes block store
store.set(block.cid.toString(), block.bytes)
return block.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 bytes = store.get(cid.toString())
// decode the DAG-JOSE envelope and verify the bytes match the CID
const block = await Block.create({ bytes, cid, codec: dagJose, hasher: sha256 })
// decrypt the encrypted payload
const decryptedData = await decryptJWE(block.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])
// create an IPLD Block that has the CID:Bytes:Value triple
const block = await Block.encode({ value: jwe, codec: dagJose, hasher: sha256 })
console.log(`Encrypted block CID: \u001b[32m${block.cid}\u001b[39m`)
console.log('Encrypted block contents:\n', block.value)
// store the block, this could be in IPFS or any other CID:Bytes block store
store.set(block.cid.toString(), block.bytes)
return block.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)
const bytes = store.get(cid.toString())
// decode the DAG-JOSE envelope
const block = await Block.create({ bytes, cid, codec: dagJose, hasher: sha256 })
if (!block.cid.equals(cid)) {
throw new Error('CID mismatch')
}
// decrypt the encrypted payload
const decryptedData = await decryptJWE(block.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!
console.log('Running symmetric example...')
symmetric().then(async () => {
console.log('Running asymmetric example...')
await asymmetric()
}).catch((e) => {
console.error(e.stack)
process.exit(1)
})