Interesting! Like I said, not a guac-crypto expert.  I read the thread, but
did not read the code, but as Chris Wheeler mentions in the linked thread,
looks like the safe approach is to add a randomized nonce in your message,
it should produce no differences in compatibility(per him), but enforce
that no messages will ever be sent identically across the wire.  i.e. in
your authString, just add a key "nonce" with a random value.

Glad you found that thread!  Goes to show security and cryptography are
hard. :)



On Wed, Feb 2, 2022 at 11:50 AM Caleb Coverdale
<[email protected]> wrote:

> From what I understood in this discussion here:
> [GUACAMOLE-1286] Support a custom IV in guacamole-auth-json - ASF JIRA
> (apache.org)
> <https://issues.apache.org/jira/projects/GUACAMOLE/issues/GUACAMOLE-1286?filter=allopenissues>
>
> There was discussion for allowing a non-null IV.
>
>
> guacamole-client/CryptoService.java at master · apache/guacamole-client
> (github.com)
> <https://github.com/apache/guacamole-client/blob/master/extensions/guacamole-auth-json/src/main/java/org/apache/guacamole/auth/json/CryptoService.java>
> In the CryptoService.js there is a comment regarding how they use the
> signature as the IV for decryption:
>
> /**
> * IV which is all null bytes (all binary zeroes). Usually, using a null IV
> * is a horrible idea. As our plaintext will always be prepended with the
> * HMAC signature of the rest of the message, we are effectively using the
> * HMAC signature itself as the IV. For our purposes, where the encrypted
> * value becomes an authentication token, this is OK.
> */
>
>
> So to me everything looks okay….
>
> So may not be the best to use the NULL IV, but there is still some
> security regarding the signature and decryption
>
>
> On Feb 2, 2022, at 12:44 PM, Craig Sawyer <[email protected]> wrote:
>
> Glad you got it figured out!
>
> I'm not up to date with Guac's crypto code-base, but in case you
> didn't know, you def. don't want to deploy with an iv of all 0's as a
> static value.  If this is just a proof of concept, no worries. Also
> you don't check any error conditions, which for production crypto code
> you most definitely will want to do.
>
> IV's are not secret, but they do need to be random(not technically,
> but practically) and never re-used.
>
> Also, this is by no means considered an audit, I don't write JS(and
> barely read the code) and am not trying to do that, just pointing out
> some glaring errors, if you were not aware, or for others trying to
> copy what you are doing down the road and not realizing IV's are
> required to match the security promises of AES-128-CBC.
>
> Good Luck.
>
> On Wed, Feb 2, 2022 at 11:07 AM Caleb Coverdale
> <[email protected]> wrote:
>
>
> Here is a copy of the fixed code incase anyone has anymore issues:
>
> const crypto = require("crypto");
>
> const key = "KEYHERE";
> const iv = "00000000000000000000000000000000";
> // convert key to binary
> const keyBin = Buffer.from(key, "hex");
> const ivBin = Buffer.from(iv, "hex");
>
> // Sign the JSON using the key with the authString using sha256/hmac
> function encryptSign(keyBin, ivBin, username, url) {
> const calculateTime = Math.floor(Date.now() / 1000) + 300;
> const expiration = calculateTime + "000";
> const authString =
> `{"username":"${username}","expires":"${expiration}","connections":{"${expiration}":{"protocol":"rdp","parameters":{"hostname":"IPHERE","port":"3389","security":"nla","ignore-cert":"true"}}}}`;
> const signature = crypto
> .createHmac("sha256", keyBin)
>
> .update(authString)
> .digest("binary");
> const signatureReturn = signature + authString;
>
> // AES-128-CBC encrypt signatureReturn using keyBin and ivBin return it in
> base64
> const cipher = crypto.createCipheriv("aes-128-cbc", keyBin, ivBin);
> const encrypted = cipher.update(signatureReturn, "binary", "base64");
> const encryptedSignature = encrypted + cipher.final("base64");
> // convert encryptedSignature to base64
>
> const urlencodedSignature = encodeURIComponent(encryptedSignature);
> const returnValue = `${url}${urlencodedSignature}`;
> return returnValue;
> }
>
> On 2022/01/26 21:00:16 Caleb Coverdale wrote:
>
> Hey there!
>
> I have been banging my head against the wall trying to get the
> EncryptedJSON script working in Javascript.
>
> I was wondering if anyone has been down the rabbit hole and got it working?
>
>
> Any help would be appreciated…
>
>
> Here’s what I have so far:
>
>
>
> const crypto = require("crypto");
> const guacjson =
> `{"username":"MyUser","connections":{"MyConnection":{"protocol":"rdp","parameters":{"hostname":"10.0.0.41","port":"3389","security":"nla","ignore-cert":"true"}}}}`;
> const secretkey = "fe57526d73a1e5116bbbefad1c91b38f";
>
> // sign the contents of guacjson with secret key using HMAC/SHA-256 out in
> binary
> function cryptedmessage() {
>  const hmac = crypto.createHmac("sha256", secretkey);
>  hmac.update(guacjson);
>  // output the hmac in binary followed by guacjson
>  signature = hmac.digest("binary") + guacjson;
>  return signature;
> }
>
> const INITIALIZATION_VECTOR = "0000000000000000";
>
> class Crypt {
>  static encrypt128(data, key) {
>    const cipher = crypto.createCipheriv(
>      "aes-128-cbc",
>      Buffer.from(key, "hex"),
>      Buffer.from(INITIALIZATION_VECTOR)
>    );
>    // return cipher encoded as bas64
>    console.log(data);
>    const encrypted =
>      cipher.update(data, "utf8", "base64") + cipher.final("base64");
>    return encrypted;
>  }
> }
>
> const key = "fe57526d73a1e5116bbbefad1c91b38f";
>
> const cipher = Crypt.encrypt128(cryptedmessage(), key);
>
> console.log(cipher);
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> <[email protected]>
> For additional commands, e-mail: [email protected]
> <[email protected]>
>
>
>

Reply via email to