Skip to content

Commit

Permalink
Add KMS code, operational decode.
Browse files Browse the repository at this point in the history
  • Loading branch information
hill399 committed Mar 26, 2021
1 parent d2cc3e9 commit aeaae01
Show file tree
Hide file tree
Showing 8 changed files with 505 additions and 30 deletions.
24 changes: 16 additions & 8 deletions masq_ea/decode.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const decrpytBuffer = require('./encrypt').decrpytBuffer;

const IPFS = require('ipfs-core');

const sg = require('./steganography/steganography');
Expand All @@ -9,21 +11,31 @@ const { JSDOM } = jsdom;
global.document = new JSDOM(`...`).window.document;
global.Image = Canvas.Image;

const decodeImage = async (args) => {
const decodeImage = async (jobRunID, args) => {
const cid = args[0];
const ipfs = await IPFS.create();

const stream = ipfs.cat(cid);

const chunks = [];

for await (const buffer of stream) {
chunks.push(buffer)
}

const buffer = Buffer.concat(chunks);
const res = sg.decode(buffer);
const bCipher = sg.decode(buffer);

return res;
const cipher = Buffer.from(bCipher, 'base64');

const message = await decrpytBuffer(cipher);

return {
jobRunID: jobRunID,
data: { "cid": cid, "complete": true },
result: true,
statusCode: 200
}
}

module.exports.decodeImage = decodeImage;
Expand All @@ -32,10 +44,6 @@ module.exports.decodeImage = decodeImage;
/*
--- TODO ---
- Migrate to cloud function.
- Implement HSM keyring.
- Decode image.
- Decode string with HSM key.
- Return CID.
- Add secure message delivery (Telegram?)
*/
21 changes: 14 additions & 7 deletions masq_ea/encode.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const encrpytBuffer = require('./encrypt').encrpytBuffer;

const IPFS = require('ipfs-core');

const sg = require('./steganography/steganography');
Expand All @@ -22,7 +24,10 @@ const uriToIpfs = async (ipfs, uri) => {
const resImage = ImageDataURI.decode(uri);
const result = await ipfs.add(resImage.dataBuffer);

return `https://ipfs.io/ipfs/${result.cid}`;
const imageUrl = `https://ipfs.io/ipfs/${result.cid}`;
const imageCid = `${result.cid}`;

return {imageUrl, imageCid};
}

const buildAndDeployMetadata = async (ipfs, url, title, desc) => {
Expand All @@ -33,7 +38,9 @@ const buildAndDeployMetadata = async (ipfs, url, title, desc) => {
};

const result = await ipfs.add(JSON.stringify(metadata));
return `https://ipfs.io/ipfs/${result.cid}`;
const metadataUrl = `https://ipfs.io/ipfs/${result.cid}`;

return metadataUrl;
}


Expand All @@ -44,16 +51,16 @@ const encodeImage = async (jobRunID, args) => {
const desc = args[3];

const imageBuffer = await getBufferFromBucket(id);
const dataUri = await sg.encode(message, imageBuffer);
const cipher = await encrpytBuffer(message);
const dataUri = await sg.encode(cipher, imageBuffer);

const ipfs = await IPFS.create();
const url = await uriToIpfs(ipfs, dataUri);
const metadataUrl = await buildAndDeployMetadata(ipfs, url, title, desc);

const {imageUrl, imageCid} = await uriToIpfs(ipfs, dataUri);
const metadataUrl = await buildAndDeployMetadata(ipfs, imageUrl, title, desc);

return {
jobRunID: jobRunID,
data: { "fileId": id, "url": metadataUrl, "result": metadataUrl },
data: { "fileId": id, "url": metadataUrl, "cid": imageCid, "result": metadataUrl },
result: metadataUrl,
statusCode: 200
}
Expand Down
78 changes: 78 additions & 0 deletions masq_ea/encrypt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Imports the Cloud KMS library
const { KeyManagementServiceClient } = require('@google-cloud/kms');
const crc32c = require('fast-crc32c');

const projectId = process.env.KSM_PROJECT_ID;
const locationId = process.env.KSM_LOCATION_ID;
const keyRingId = process.env.KSM_KEYRING_ID;
const keyId = process.env.KSM_KEY_ID;

// Instantiates a client
const client = new KeyManagementServiceClient({
keyFilename: "./serviceAccount.json"
});

const keyName = client.cryptoKeyPath(projectId, locationId, keyRingId, keyId);

// Build the key name
const encrpytBuffer = async (plaintext) => {
const buffer = Buffer.from(plaintext);
// Optional, but recommended: compute plaintext's CRC32C.
const bufferCrc32c = crc32c.calculate(buffer);

const [encryptResponse] = await client.encrypt({
name: keyName,
plaintext: buffer,
plaintextCrc32c: {
value: bufferCrc32c,
},
});

const ciphertext = encryptResponse.ciphertext;

if (!encryptResponse.verifiedPlaintextCrc32c) {
throw new Error('Encrypt: request corrupted in-transit');
}
if (
crc32c.calculate(ciphertext) !==
Number(encryptResponse.ciphertextCrc32c.value)
) {
throw new Error('Encrypt: response corrupted in-transit');
}

console.log(`Ciphertext: ${ciphertext.toString('base64')}`);

return ciphertext.toString('base64');
}

const decrpytBuffer = async (cipher) => {

const ciphertextCrc32c = crc32c.calculate(cipher);

const [decryptResponse] = await client.decrypt({
name: keyName,
ciphertext: cipher,
ciphertextCrc32c: {
value: ciphertextCrc32c,
},
});

// Optional, but recommended: perform integrity verification on decryptResponse.
// For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
// https://cloud.google.com/kms/docs/data-integrity-guidelines
if (
crc32c.calculate(decryptResponse.plaintext) !==
Number(decryptResponse.plaintextCrc32c.value)
) {
throw new Error('Decrypt: response corrupted in-transit');
}

const plaintext = decryptResponse.plaintext.toString('utf8');

console.log(`Plaintext: ${plaintext}`);
return plaintext;

}

module.exports.encrpytBuffer = encrpytBuffer;
module.exports.decrpytBuffer = decrpytBuffer;
8 changes: 4 additions & 4 deletions masq_ea/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ const decodeImage = require('./decode').decodeImage;

const customParams = {
func: ['func'],
fileId: ['fileId'],
message: ['message'],
title: ['title'],
desc: ['desc'],
fileId: false,
message: false,
title: false,
desc: false,
url: false
}

Expand Down
1 change: 1 addition & 0 deletions masq_ea/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"@chainlink/external-adapter": "^0.2.6",
"@google-cloud/storage": "^5.8.1",
"canvas": "^2.7.0",
"dotenv": "^8.2.0",
"image-data-uri": "^2.0.1",
"ipfs-core": "^0.5.4",
"jsdom": "^16.5.1"
Expand Down
5 changes: 5 additions & 0 deletions masq_ea/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,11 @@ dot-prop@^5.1.0, dot-prop@^5.2.0:
dependencies:
is-obj "^2.0.0"

dotenv@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==

duplexify@^3.6.0:
version "3.7.1"
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309"
Expand Down
Loading

0 comments on commit aeaae01

Please sign in to comment.