Is it possible to send an encrypted message from unificationengine?
I have added a connector to my app.
How to send an encrypted message from unificationengine to my social media?
Yes, it is possible to send an encrypted message.
curl -XPOST https://apiv2.unificationengine.com/v2/message/send --data "{ \"message\": { \"receivers\": [{\"name\": \"name\", \"address\": \"RECEIVER_ADDRESS\" , \"Connector\": \"CONNECTOR_NAME\", \"uri\":\"zalo://ENCRYPTED_URI#zalo.com\"}],\"subject\":\"\",\"parts\": [{\"id\": \"4\",\"contentType\": \"text/plain\", \"data\":\"ENCRYPTED_MESSAGE_CONETENT\" ,\"size\": MESSAGE_SIZE,\"type\": \"body\",\"sort\":0}]}}" -u USER_ACCESSKEY:USER_ACCESSSECRETc -k
ENCRYPTED_URI = encrypted uri (CONNECTOR_SCHEME://ACCESS_TOKEN:ACCESS_SECRET#CONNECTOR_SCHEME.com) using openpgp.
ENCRYPTED_MESSAGE_CONETENT = encrypted message data using openpgp
Related
In NodeJS I'm trying to verify a message was sent by Google before processing the message contents.
This is done by comparing the message header "x-goog-signature" to a generated signature.
The generated signature code takes as input the service account key and the http raw body.
Following this example.
let generatedSignature = require('crypto').createHmac('sha512', partnerKey).update(Buffer.from(req.rawBody, 'utf8')).digest('base64');
This is the key from which I parse the private_key value.
{
"type": "service_account",
"project_id": "XXXX",
"private_key_id": "XXXXXXX",
"private_key": "-----BEGIN PRIVATE KEY-----\nXXXXXXXXXXXXX\nXXXXXXXXXXXXXX\n-----END PRIVATE KEY-----\n",
"client_email": "XXXX",
"client_id": "XXXXXXX",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/dev-gary%40asc-gbm-registration-proj.iam.gserviceaccount.com"
}
And getting raw body from httpRequest.
httpRequest.rawBody
But the resulting generated signature is not the same as the x-goog-signature.
The private_key value has a prefix and postfix which I've removed. Also tried without the \n newline chars.
Any help would be appreciated.
The example you're referring to seems to answer your question with a link:
/**
* Verify the message is from Google.
* Learn more in the [documentation](https://developers.google.com/business-communications/business-messages/guides/build/receive#verify).
*
* #param {string} message The message text received from the user.
* #param {string} conversationId The unique id for this user and agent.
*/
function validateMessage(message, conversationId) {}
The link is just meanwhile: https://developers.google.com/business-communications/business-messages/guides/how-to/message/receive#verify.
There's even a precise example, but I cannot find where it validates the X-Goog-Signature header: https://github.com/google-business-communications/bm-nodejs-echo-bot/tree/master/message_validation_sample
And I also think it's HMAC / SHA256 / Base64 - but the docs explicitly say SHA512 (it wouldn't hurt to try both). Also the header string matters; the input string must be processed exactly alike the server-side did it, else the comparison won't match.
let generatedSignature = require('crypto')
.createHmac('sha512', partnerKey)
.update(Buffer.from(req.rawBody, 'utf8'))
.digest('base64');
That "partnerKey" likely is not a service-account credentials JSON (not sure what they've sent):
After Google registers your project, Google sends you a confirmation email with your partner information, including a Partner ID and an Partner key (formerly "CRM key" or "authorization key").
It is probably save to assume, that this confirmation email holds the key to the solution.
I am trying to run Microsoft graph API to generate token. This is working fine in postman but failed in SoapUI. I think client secret has special characters which are causing the issue.
client secret:
osi5oX-:?0A3YiG4aCpZ.Y[+PW51pZVY
API URL (POST) :
https://login.microsoftonline.com/{tenantID}/oauth2/v2.0/token
Body:
client_id=xxxxx&client_secret=osi5oX-:?0A3YiG4aCpZ.Y[+PW51pZVY&grant_type=client_credentials&scope=https://graph.microsoft.com/.default
Error:
{"error":"invalid_client","error_description":"AADSTS7000215: Invalid client secret is provided.\r\nTrace ID: 32b5bf83-f908-4b4e-9fe6-5b05fd949e00\r\nCorrelation ID: b9b7ce92-f5d1-41d1-8d92-eed8a6a5470b\r\nTimestamp: 2020-05-07 17:27:08Z","error_codes":[7000215],"timestamp":"2020-05-07 17:27:08Z","trace_id":"32b5bf83-f908-4b4e-9fe6-5b05fd949e00","correlation_id":"b9b7ce92-f5d1-41d1-8d92-eed8a6a5470b","error_uri":"https://login.microsoftonline.com/error?code=7000215"}
Use secret after encoding and it works.
import java.net.URLEncoder;
String url = "osi5oX-:?0A3YiG4aCpZ.Y[+PW51pZVY"
String encodedUrl = URLEncoder.encode(url, "UTF-8" );
println(encodedUrl)
how can I get the consumer key, Signature and consumer secret(dynamically) from the server(OAuth1). So, that I can pass it in Headers->Authorization to execute my routes(register) in Postman.
I was able to get consumer key and Signature by registering client by making POST request at {{url}}/api/client/register
Sent the following code in the Body:
{
"type": "client_associate",
"application_name": "Your Application Name",
"application_type": "web"
}
I have had great success with the Microsoft Graph API to access users etc etc within Azure Active Directory, however two things that still require EWS and SOAP are retrieving user photos and adding a mail rule to a users mail account.
I'm using Service accounts for everything, and impersonating an account admin to make requests.
After attempting to use the same access token that I am using against the Graph API, I receive the error:
The access token is acquired using an authentication method that is too weak to allow access for this application. Presented auth strength was 1, required is 2.
Reading around, I understand that because EWS requires full privileges against the accounts, you can't just pass the access token, but you also have to "do something" with an x509 certificate.
In my registered app, within Azure, I have adjusted the manifest so to include a self signed certificate so that I have:
"keyCredentials": [{
"customKeyIdentifier": "lhbl...../w0bjA6l1mQ8=",
"keyId": "774D2C35-2D58-.....-AC34B15472BA",
"type": "AsymmetricX509Cert",
"usage": "Verify",
"value": "MIIFtTCCA52gAwIB.....mmgufQ2rW5GSjEEXOlO1c7qw=="
}],
My understanding is the customKeyIdentifier is the Base64 of the key, from the command: echo $(openssl x509 -in cert.pem -fingerprint -noout) | sed 's/SHA1 Fingerprint=//g' | sed 's/://g' | xxd -r -ps | base64
the value is literally the key content, with the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- removed, and all new lines removed too (otherwise in the manifest, the json isn't valid).
The keyId is a GUID I just generated on the terminal with the uuidgen command, I don't think its related directly to the certificate in any way.
What I'm not sure then, is what I have to change within my code, that is going to try to auth against EWS.
I have started out with the node-ews library, my configuration looks like:
var ewsConfig = {
username: userEmail,
token: self.accessToken,
host: 'https://outlook.office365.com/EWS/Exchange.asmx',
auth: 'bearer'
};
var ews = new EWS(ewsConfig);
var ewsFunction = 'UpdateInboxRules';
ews.run(ewsFunction, ewsArgs)
.then(result => {
cb(null, result)
})
.catch(err => {
cb(err);
});
};
self.accessToken is the same token that I receive when accessing the Microsoft Graph API.
So, in conclusion, my questions are:
What do I need to do to my request so that I am telling the server to also auth the x509 certificate, I read that I may need to convert it to a PKCS12 certicificate also?
Can I use the same accessToken that I am successfully using to access the graph api?
Is there a code snippet anywhere for Nodejs doing this?
Is the keyId ok to be any identifier I want to give it?
The response I get back contains:
{ 'content-length': '0',
server: 'Microsoft-IIS/8.5',
'request-id': '9b0d7a1b-85e6-40f6-9af0-7f65fc6669dc',
'x-calculatedfetarget': 'MM1P123CU001.internal.outlook.com',
'x-backendhttpstatus': '401, 401',
'set-cookie': [Object],
'x-feproxyinfo': 'MM1P123CA0026.GBRP123.PROD.OUTLOOK.COM',
'x-calculatedbetarget': 'MM1P123MB1337.GBRP123.PROD.OUTLOOK.COM',
'x-ms-diagnostics': '2000001;reason="The access token is acquired using an authentication method that is too weak to allow access for this application. Presented auth strength was 1, required is 2.";error_category="invalid_token"',
'x-diaginfo': 'MM1P123MB1337',
'x-beserver': 'MM1P123MB1337',
'x-feserver': 'MM1P123CA0026, VI1PR0701CA0059',
'x-powered-by': 'ASP.NET',
'www-authenticate': 'Bearer client_id="00000002-0000-0ff1-ce00-000000000000", trusted_issuers="00000001-0000-0000-c000-000000000000#*", token_types="app_asserted_user_v1 service_asserted_app_v1", authorization_uri="https://login.windows.net/common/oauth2/authorize", error="invalid_token",Basic Realm="",Basic Realm="",Basic Realm=""',
date: 'Tue, 02 May 2017 18:08:54 GMT',
connection: 'close' } }
Thanks, much appreciated
I followed this article to generate access_token https://blogs.msdn.microsoft.com/arsen/2015/09/18/certificate-based-auth-with-azure-service-principals-from-linux-command-line/, did have some issues with jwt signing, I had to use openssl rsa -check -in key.pem to decrypt the key and save it in a text file. then jwt signing worked. You also need to be impersonating, see this https://github.com/CumberlandGroup/node-ews/issues/39
it may help with node-ews. I have not tested this scenario with node-ews. If you are interested in looking at more robust approach with ews managed api like coding, I have ported c# version of ews-managed-api to ews-javascript-api , here is the sample code to achieve same with ews-javascript-api, tested and confirmed working code.
var ews = require("ews-javascript-api");
ews.EwsLogging.DebugLogEnabled = false;
var exch = new ews.ExchangeService(ews.ExchangeVersion.Exchange2013);
exch.Credentials = new ews.OAuthCredentials("oauth access_token");
exch.Url = new ews.Uri("https://outlook.office365.com/Ews/Exchange.asmx");
exch.ImpersonatedUserId = new
ews.ImpersonatedUserId(ews.ConnectingIdType.SmtpAddress, "user#domain.com");
exch.HttpHeaders = { "X-AnchorMailbox": "user#domain.com" };
var rule = new ews.Rule();
rule.DisplayName = "MoveInterestingToJunk";
rule.Priority = 1;
rule.IsEnabled = true;
rule.Conditions.ContainsSubjectStrings.Add("Interesting");
rule.Actions.MoveToFolder = new ews.FolderId(ews.WellKnownFolderName.JunkEmail);
var ruleop = new ews.CreateRuleOperation(rule);
exch.UpdateInboxRules([ruleop], true)
.then(function (response) {
console.log("success - update-inboxrules");
ews.EwsLogging.Log(response, true, true);
}, function (err) {
debugger;
console.log("error in update-inboxrules");
ews.EwsLogging.Log(err, true, true);
});
I'm working on authentication for my JSON-RPC API and my current working strategy is using signed requests sent via POST over SSL.
I'm wondering if anyone can see any vulnerabilities that I haven't taken into consideration with the following signature method.
All communication between the client and the server is done via POST requests sent over SSL. Insecure http requests are denied outright by the API server.
Dependencies
var uuid = require('node-uuid');
var crypto = require('crypto');
var moment = require('moment');
var MyAPI = require('request-json').newClient('https://api.myappdomain.com');
Dependency Links: node-uuid, crypto, moment, request-json
Vars
var apiVersion = '1.0';
var publicKey = 'MY_PUBLIC_KEY_UUID';
var secretKey = 'MY_SECRET_KEY_UUID';
Request Object
var request = {
requestID : uuid.v4(),
apiVersion : apiVersion,
nonce : uuid.v4(),
timestamp : moment.utc( new Date() ),
params : params
}
Signature
var signature = crypto.createHmac('sha512',secretKey).update(JSON.stringify(request)).digest('hex');
Payload Packaging (Sent as cleartext via POST over SSL)
var payload = {
request: request,
publicKey : publicKey,
signature : signature
}
Resultant Payload JSON Document
{
"request" : {
"requestID" : "687de6b4-bb02-4d2c-8d3a-adeacd2d183e",
"apiVersion" : "1.0",
"nonce" : "eb7e4171-9e23-408a-aa2b-cd437a78af22",
"timestamp" : "2014-05-23T01:36:52.225Z",
"params" : {
"class" : "User"
"method" : "getProfile",
"data" : {
"id" : "SOME_USER_ID"
}
}
},
"publicKey" : "PUBLIC_KEY",
"signature" : "7e0a06b560220c24f8eefda1fda792e428abb0057998d5925cf77563a20ec7b645dacdf96da3fc57e1918950719a7da70a042b44eb27eabc889adef95ea994d1",
}
POST Request
MyAPI.post('/', payload, function(response){
/// Handle any errors ...
/// Do something with the result ...
/// Inspect the request you sent ...
});
Server-Side
And then on the server-side the following occurs to authenticate the request:
PUBLIC_KEY is used to lookup the SECRET_KEY in the DB.
SECRET_KEY is used to create an HMAC of the request object from the payload.
The signature hash sent in the payload is compared to the hash of the request object created on the server. If they match, we move on to authenticating the timestamp.
Given that we can now trust the timestamp sent in the cleartext request object since it was included in the signature hash sent from the client, the timestamp is evaluated and the authentication is rejected if the request is too old. Otherwise, the request is authenticated.
So far as I understand, this is a secure method for signing and authentication requests sent over SSL. Is this correct?
Thanks in advance for any help.
Update on JSON Property Order
The order of properties when using JSON.stringify is essentially random, which could cause signature mis-matches.
Using this signing process over the past few weeks I haven't run into any hash mis-match issues due to the order of the properties in the JSON request object. I believe it's because I only stringify the request object literal once, right before the client-side hash is calculated. Then, the request object is in JSON format as part of the payload. Once received by the server, the hash is created directly from the JSON object received in the payload, there's no second JSON.stringify method invoked, so the signature always matches because the order of the properties is determined once, by the client. I'll keep looking into this though as it seems like a weak point, if not a security concern.
JSON.stringify does not guarantee order of properties. For example, object
{
a: 1,
b: 2
}
could be serialized in two ways: {"a":1,"b":2} or {"b":2,"a":1}. They are the same from JSON point of view but they will result it different HMACs.
Imaging, that for signings your JSON.stringify produced first form, but for checking signature second one. Your signature check will fail although signature was valid.
The only fishy thing I see here would be the JSON.stringify as posted in other comments, but you can use:
https://www.npmjs.com/package/json-stable-stringify
That way you can have a deterministic hash for you signs.