I'm trying to encrypt text with OpenPGPJS in react application.
I have a function in react class:
const openpgp = require('openpgp');
...
class XYZ extends React.Component{
...
async encrypt(text, targetKey){
await openpgp.initWorker({ path: 'openpgp.worker.js' });
var publicKey = (await openpgp.key.readArmored(targetKey.trim())).keys;
console.log(publicKey);
const result = await openpgp.encrypt({
message: openpgp.message.fromText(text),
publicKeys: publicKey
});
console.log(result.data);
}
...
const public_key = `-----BEGIN PGP PUBLIC KEY BLOCK----- .......`
const text = 'encrypt this'
this.encrypt(text, public_key);
for encryption.
I get an error message: Unhandled Rejection (Error): Error encrypting message: No keys, passwords, or session key provided.
I find out that (await openpgp.key.readArmored(targetKey.trim())).keys; return empty array, idk why.
Related
I am getting error TypeError: Cannot read property 'readArmored' of undefined when running below code , I am not sure what I am missing. I am trying to encrypt and decrypt files with PGP key.
const openpgp = require('openpgp');
(async () => {
const { privateKey, publicKey } = await openpgp.generateKey({
type: 'ecc', // Type of the key, defaults to ECC
curve: 'curve25519', // ECC curve name, defaults to curve25519
userIDs: [{ name: 'Jon Smith', email: 'jon#example.com' }], // you can pass multiple user IDs
passphrase: 'super long and hard to guess secret', // protects the private key
format: 'armored' // output key format, defaults to 'armored' (other options: 'binary' or 'object')
})
console.log(privateKey) // '-----BEGIN PGP PRIVATE KEY BLOCK ... '
console.log(publicKey) // '-----BEGIN PGP PUBLIC KEY BLOCK ... '
const encrypted = await openpgp.encrypt({
message: await openpgp.createMessage({ text: 'Hello, World!' }),
publicKeys: (await openpgp.key.readArmored(`${publicKey}`)).keys
})
console.log(encrypted)
})()
I am trying to connect web3js in the javascript section of my html to my ganache-cli nodejs server
ganache deployment script:
const ganache = require("ganache-cli");
const Web3 = require("web3");
const web3 = new Web3(ganache.provider());
const { interface, bytecode } = require("./compile");
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
const result = await new web3.eth.Contract(JSON.parse(interface))
.deploy({
data: bytecode,
arguments: ["test"],
})
.send({ from: accounts[0], gas: "1000000" });
console.log(`Contract address: ${result.options.address}`);
};
var server = ganache.server();
server.listen(8545, function (err, blockchain) {
console.log(server);
console.log(" live at port 8545");
});
deploy();
my frontend html/js file
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:8545"));
web3.eth.defaultAccount = web3.eth.accounts[0];
var info = new web3.eth.Contract(
JSON.parse(interface), '0xeD9a9f326F38223a6599309F7201562DfB177997');
console.log(info.methods.GetInfo("test").call());
}
But I get the following error:
index.js:297 Uncaught (in promise) Error: Returned values aren't valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node which is not fully synced.
solidty code:
pragma solidity ^0.4.17;
pragma experimental ABIEncoderV2;
contract DVA {
struct Info {
// uint Age;
// bool AgeRestriction;
string DO_Num;
string date;
string time;
string status;
string otherstatus;
string imagehash;
string imagename;
}
mapping (string => Info[]) AllInfo;
function SetInfo(string _DO, string _date, string _time, string _status, string _otherstatus, string _imagehash, string _imagename) public {
Info memory info = Info(_DO,_date,_time,_status,_otherstatus,_imagehash,_imagename);
AllInfo[_DO].push(info);
}
function GetInfo(string _DO) public view returns (string memory) {
// return (AllInfo[_DO].status,AllInfo[_DO].time);
return "hi";
}
}
The code above is the contract code.
The weird thing is, I can call SetInfo but not GetInfo. I have ensured the contract address is valid, and that the ABI is correct as well. In fact, the ABI is retrieved directly upon each compilation of the solidty code as well.
I am using Jest to test a small function of mine that makes use of OpenPGP.js https://openpgpjs.org/ (the latest version, 4.10.9).
I saw some workarounds using the library text-encoding-utf-8 and I did this on my tests, but unfortunately, the error persists.
Even with:
const textEncoding = await import("text-encoding-utf-8")
global.TextEncoder = textEncoding.TextEncoder
global.TextDecoder = textEncoding.TextDecoder
My function:
import * as openpgp from "openpgp"
export async function decryptMessage(privateKeyArmored, passphrase, message) {
const {
keys: [privateKey],
} = await openpgp.key.readArmored(privateKeyArmored)
await privateKey.decrypt(passphrase)
const { data } = await openpgp.decrypt({
message: await openpgp.message.readArmored(message),
privateKeys: [privateKey],
})
return data
}
And this is my test
import * as openpgp from "openpgp"
import { decryptMessage } from "../src/crypto"
let privateKey
let publicKey
const passphrase = "password"
const oldTextEncoder = global.TextEncoder
const oldTextDecoder = global.TextDecoder
describe("crypto test suite", () => {
beforeAll(async () => {
// workaround to openpgp works with jest
const textEncoding = await import("text-encoding-utf-8")
global.TextEncoder = textEncoding.TextEncoder
global.TextDecoder = textEncoding.TextDecoder
const { privateKeyArmored, publicKeyArmored } = await openpgp.generateKey({
userIds: [{ name: "username" }],
curve: "ed25519",
passphrase,
})
privateKey = privateKeyArmored
publicKey = publicKeyArmored
})
afterAll(() => {
global.TextEncoder = oldTextEncoder
global.TextDecoder = oldTextDecoder
})
test("decrypt message", async () => {
const text = "test"
const { data } = await openpgp.encrypt({
message: openpgp.message.fromText(text),
publicKeys: (await openpgp.key.readArmored(publicKey)).keys,
})
const result = decryptMessage(privateKey, passphrase, data)
expect(result).toBe(text)
})
})
When I run, I got:
(node:10804) UnhandledPromiseRejectionWarning: Error: concatUint8Array: Data must be in the form of a Uint8Array
(node:10804) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 25)
Any clues?
I was getting the same issue and then I had to use a specific openpgp version. This is what ended up working for me:
"openpgp": "4.10.10",
"text-encoding-utf-8": "^1.0.2",
So, I had to use the proper functions inherent to this openpgp version as follows:
test('Encrypts a file using the GPG file', async () => {
const textEncoding = await import("text-encoding-utf-8")
global.TextEncoder = textEncoding.TextEncoder
global.TextDecoder = textEncoding.TextDecoder
const publicKey = fs.readFileSync('/path/file.asc')
const input = fs.createReadStream('a.txt')
const encrypted = await openpgp.encrypt({
message: await openpgp.message.fromBinary(input),
publicKeys: (await openpgp.key.readArmored(publicKey)).keys,
})
console.log(encrypted)
Let me know if it works for you
I'm using openpgp.js version 2.2.1.
So I've managed to encrypt a message just fine
const options = {
data: voteObject.option, // input as Message object
publicKeys: (pgp.key.readArmored(pubkey)).keys, // for encryption
};
pgp.encrypt(options).then(function(ciphertext) {
console.log(ciphertext.data);
});
This logs the encrypted message. The problem I'm now having is that I can't decrypt it. I'm at a complete loss at this point and to be honest I've tried everything to the point I don't know what I'm doing anymore. I know this isn't much to work with but I don't really have anything else to give.
Any suggestions at all would be a huge help!
I think you are mixing up the passphrase for a key and the password for "simply" encrypting a string.
Usually, in PGP a sender is encrypting a message with the receiver's public key. The receiver of the message can then decrypt his private key with his secret passphrase and with the resulting decrpyted private key he can decrypt the message.
I added a working example below:
Encryption
const receiverPublicKey = ...;
let publicKeys = (await openpgp.key.readArmored(receiverPublicKey)).keys;
let options = {
data: 'Hello, World!',
publicKeys: publicKeys
};
return openpgp.encrypt(options)
.then((encryptedMessageObject) => {
return encryptedMessageObject.data; // -----BEGIN PGP MESSAGE----- ... wcBMA0rHUQJA4dCdAQg...
});
Decryption
const receiverPrivateKey = ...;
const receiverPassphrase = 'secret';
const encryptedMessage = '-----BEGIN PGP MESSAGE----- ... wcBMA0rHUQJA4dCdAQg...';
let privKeyObj = (await openpgp.key.readArmored(receiverPrivateKey)).keys[0];
await privKeyObj.decrypt(receiverPassphrase);
let options = {
message: await openpgp.message.readArmored(encryptedMessage),
privateKey: privKeyObj
};
return openpgp.decrypt(options)
.then((plaintextObject) => {
return plaintextObject.data; // Hello, World!
});
This is the usual process of using PGP with one sender and one receiver (note that the signing of the message and checking the signature is missing).
Now there's also password in the decrypt options.
For that, see the example from the docs:
var options, encrypted;
options = {
data: 'Hello, World!', // input as String
passwords: ['secret stuff'] // multiple passwords possible
};
openpgp.encrypt(options).then(function(ciphertext) {
encrypted = ciphertext.data; // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----'
});
options = {
message: openpgp.message.readArmored(encrypted), // parse armored message
password: 'secret stuff' // decrypt with password
};
openpgp.decrypt(options).then(function(plaintext) {
return plaintext.data; // 'Hello, World!'
});
In this case, a password is used to encrypt and decrypt a message - no public or private key at all.
I hope that helps!
I am trying to implement a very simple dialogflow agent integration with nodejs.
Here is what I did so far
I followed the code from Intent detection
I added the service account private key file .json to my server.
I added the environment variable GOOGLE_APPLICATION_CREDENTIALS with the path to my .json private key file.
Here is the code I am trying to run right now:
require('dotenv').config()
const projectId = 'gg-chatbot-216808';
const sessionId = 'quickstart-session-id';
const query = 'hello';
const languageCode = 'en-US';
// Instantiate a DialogFlow client.
const dialogflow = require('dialogflow');
const sessionClient = new dialogflow.SessionsClient();
// Define session path
const sessionPath = sessionClient.sessionPath(projectId, sessionId);
// The text query request.
const request = {
session: sessionPath,
queryInput: {
text: {
text: query,
languageCode: languageCode,
},
},
};
// This prints the private key path correctly.
console.log(process.env.GOOGLE_APPLICATION_CREDENTIALS);
// Send request and log result
sessionClient
.detectIntent(request)
.then(responses => {
console.log('Detected intent');
const result = responses[0].queryResult;
console.log(` Query: ${result.queryText}`);
console.log(` Response: ${result.fulfillmentText}`);
if (result.intent) {
console.log(` Intent: ${result.intent.displayName}`);
} else {
console.log(` No intent matched.`);
}
})
.catch(err => {
console.error('ERROR:', err);
});
Then I get this error in the console when I run this file
Auth error:Error: invalid_user: Robot is disabled.
ERROR: { Error: 14 UNAVAILABLE: Getting metadata from plugin failed with error: invalid_user: Robot is disabled.
at Object.exports.createStatusError (/var/www/html/google_auth/node_modules/grpc/src/common.js:87:15)
at Object.onReceiveStatus (/var/www/html/google_auth/node_modules/grpc/src/client_interceptors.js:1188:28)
at InterceptingListener._callNext (/var/www/html/google_auth/node_modules/grpc/src/client_interceptors.js:564:42)
at InterceptingListener.onReceiveStatus (/var/www/html/google_auth/node_modules/grpc/src/client_interceptors.js:614:8)
at callback (/var/www/html/google_auth/node_modules/grpc/src/client_interceptors.js:841:24)
code: 14,
metadata: Metadata { _internal_repr: {} },
details: 'Getting metadata from plugin failed with error: invalid_user: Robot is disabled.' }
i also faced a similar issue for my angular bot.
What i did was, instead of using using the google_credentials from the json file, i created an object with private_key,client_email {these values can be taken from the service account private key file .json}, and passed the object while setting up the session client.
var config = {
credentials: {
private_key: "YOUR_PRIVATE_KEY",
client_email: "YOUR_CLIENT_EMAIL"
}
}
const sessionClient = new dialogflow.SessionsClient(config);
note: do copy the full private_key string from .json. It will start as "-----BEGIN PRIVATE KEY-----\n......" .
Also, in GCP go to the project->IAM then try setting role for the service as DIALOGLOW API ADMIN. Check if this works.
If this has not been resolved yet , the solution is to provide "fileKey" inside sessionClient.
const sessionClient = new dialogflow.SessionsClient({
fileKey:" path of your credentials.json file"
});
or
let filePath = process.env.GOOGLE_APPLICATION_CREDENTIALS ="Location of credentials file".
const sessionClient = new dialogflow.SessionsClient({
fileKey:filePath
});
this will even work if there is no system env variable is set as GOOGLE_APPLICATION_CREDENTIALS.
Hope this is helpful.