any help/directions to try and test will be really...
# suitescript
s
any help/directions to try and test will be really nice, stuck with the last part of a RSA256 JWT... cant for the love of god pull this damn multiline private key file from the api secrets module, the logs just keep slapping me with a
Copy code
{
   Error: {
      type: "error.SuiteScriptError",
      name: "AN_ERROR_OCCURRED_WHILE_DECRYPT_PASSWORDGUID",
      message: "An error occurred while decrypting a credential."
   }
}
Aint even trying a guid though damn, or just tell me its impossible because of a secure string issue and i'll try to shim my way towards light? (if thats even possible?)
Copy code
require(['N/record','N/runtime','N/search','N/format',"N/encode","N/crypto"], function(record,runtime,search,format,encode,crypto) {
  try{
    var header = 'base64_clean_str1';
    var body = 'base64_clean_str2';
    var privateKey = "{custsecret_1}";
        
    var rsa4096 = crypto.createSecretKey({
    secret: privateKey,
    encoding: encode.Encoding.UTF_8
 });

    var biscuit = crypto.createHmac({
    algorithm: crypto.HashAlg.SHA256,
    key:rsa4096
 });

 biscuit.update({
    input:header +"."+ body,
    inputEncoding: encode.Encoding.UTF_8
 });

    var signature = biscuit.digest({
    outputEncoding:encode.Encoding.BASE_64_URL_SAFE
 })

    log.debug("signature",signature);

  var abc = 1;

  } catch (e) {
    var scriptId = runtime.getCurrentScript().id;
    log.error('ERROR:'+scriptId+':fn:'+runtime.executionContext, JSON.stringify({type: e.type,name: e.name,message: e.message,stack: e.stack,cause: JSON.stringify(e.cause),id: e.id}));
  }
});
b
its extremely unlikely that your private key is encoded using utf-8
your private key is a bunch of bytes and utf-8 doesnt represent all bytes
s
I may be attempting some manual JWT generation as well - was assuming I would leverage the
Certificates
store in NS?
s
@battk its one of those that go
Copy code
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDB676k31ygRVmc
...
vDFbIqe9mWaLPZ+eGTMVXqxGYZgpC0f47jnr0om3jzFFLM7+zDhztIRkXnfHKNJk
GUFNkknDR6s+oCA/Xej+utA/tUf2nQ==
-----END PRIVATE KEY-----
it the code example in node that i got working they load it as a utf-8
Copy code
const apiSecret = fs.readFileSync("secret.key", "utf8");
but i'm not sure thats how i should upload to NS too...
b
thats a private key for use in asymmetric encryption
thats not what you would use for a hmac
its also in pem format, which has a header and trailer
though the actual content is base 64 encoded
again, not utf 8
s
you're right I did some research and its asym because i'm doing RS256, not the HS256, but my other file isn't a pem. but a csr file. I'm not a cryptography expert, but from research so far I think I can use the synchronous method, with the private key?
b
there is no support for asymmetric crypto in suitescript
thats not strictly true, there is a certificate module, but its vary narrow in scope
s
@battk do you think in theory use cryptojs with a shim? and leave it out of the secure string?
b
same answer actually, there is no support for asymmetric crypto in cryptojs
s
@battk i did find this jsrsasign, i guess this is the last straw to try then
actually @battk , what i'm confused about also is i'm actually signing with the private key, do you think it could by symmetric crypto if the certificate was a "public" key? instead?
@battk i think i'll open a case with advanced partner support to see if the issue is with me pulling the secret, and then probably we can see if its theory, technology of just bad ideas haha
b
short answer is no, long answer is you dont know the difference between encryption and digital signature/signing
🙌 1
s
It looks like they are trying to do signing, not encryption.
I'll have an opportunity to work with the certificates module later this week and will report back if any success
s
@battk true. what I do know is I have only one set of keys in common to both systems, hopefully that puts me on symmetric the csr that I uploaded verified against the private key on their system api-sdk, so probably something in the signature generation is wrong for me but for me I do need to figure out the technology and theory
thanks @Shawn Talbert i'll also update if i get the come back, actuallwith the jwt i did pass the first two dots, not the signature but with the signature their api-sdk test results came out same as the authentic jwt (no surprise) so its just up to figuring out the last bit which is
Copy code
crypto.createHash("sha256").update(JSON.stringify(bodyJson || "")).digest().toString("hex")
hopefully not async
b
thats a hmac, which should correspond to HS256
ablobsweating 1
s
@battk OK, so that means where i broke is probably indeed netsuite side 😂
b
actually, that isnt a hmac
thats just a plain hash
thats not encryption at all
s
@battk you're right, thats just a hash on the header that's signed can we break it down further?
b
a hash would only be useful if there is some other encryption going on inside that body json
and it would be unlikely to be asymmetric, both client and server would need to be able to generate the same json body and see if the hashes match
in asymmetric algorithms rely on 2 parties having different parts of the same key (the public and private keypair)
s
@battk indeed, i think what this is is a HS256 variant, but the signed key is different
I assume what is happening is HS256, but instead of having the key that decrypts it, you either figure out something thats in common or you get something that verifies that its true, even though you dont know what it is
in a non-mathematical way of saying
b
meh, im assuming something is missing
a jwt looks like
Copy code
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.NHVaYe26MbtOYhSKkoKYdFVomg4i8ZJd8_-RU8VNbftc4TSMb4bXP3l3YlNWACwyXPGffz5aXHc6lty1Y2t4SWRqGteragsVdZufDn5BlnJl9pdR_kdVFUsra2rWKEofkZeIC4yWytE58sMIihvo9H1ScmmVwBcQP6XETqYd0aSHp1gOa9RdUPDvoXQ5oqygTqVtxaDr6wUFKrKItgBMzWIdNZ6y7O9E0DhEPTbE9rfBo6KTFsHAZnMg4k68CDp2woYIaXbmYTWcvbzIuHO7_37GT79XdIwkm95QJ7hYC9RiwrV7mesbY4PAahERJawntho0my942XheVLmGwLMBkQ
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9 is the base 64 encoded header, decoded it looks like
Copy code
{
  "alg": "RS256",
  "typ": "JWT"
}
it tells you what it is and what algorithm its using
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0 is the base 64 encoded payload, decoded it looks like
Copy code
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022
}
it has the data that you wanted verified
Copy code
NHVaYe26MbtOYhSKkoKYdFVomg4i8ZJd8_-RU8VNbftc4TSMb4bXP3l3YlNWACwyXPGffz5aXHc6lty1Y2t4SWRqGteragsVdZufDn5BlnJl9pdR_kdVFUsra2rWKEofkZeIC4yWytE58sMIihvo9H1ScmmVwBcQP6XETqYd0aSHp1gOa9RdUPDvoXQ5oqygTqVtxaDr6wUFKrKItgBMzWIdNZ6y7O9E0DhEPTbE9rfBo6KTFsHAZnMg4k68CDp2woYIaXbmYTWcvbzIuHO7_37GT79XdIwkm95QJ7hYC9RiwrV7mesbY4PAahERJawntho0my942XheVLmGwLMBkQ
is the signature, which has the crypto payload in there
ill ignore how to generate it, but it requires knowing whats inside the jwt's header and payload
s
@battk indeed, and my current issue i've had is either the last part is super short, or i'm getting the GUID error
it's so many characters short I think it feels like it loaded null or the equivalent
b
im not sure what json body you are hashing, but once its hashed, the receiver of the hash wont be able to tell what the original data was
s
i mean i'm checking the signature and its
Copy code
AslST2owWI56Akl2t0QYTLZCnsvqEUJyJV6oUVuyGbM
vs
Copy code
jsnBEBlcogkB2MHQmH2axqAKdK5splDXnrzZ_MHWaCeKqoX-kMorQzuEltUIuTM1PXFC_5ts9YqiWon7M4ye9fQ8l4xye9M4pXf_TqVAOsm9sJsYxDbEcyeZkNQ5A9mZfXwQ8JaFj6_a56ovEaupsQX2aa0AVVo0hihwnHAF0Ubn0MgnkEqQ6Ax2EWoJrPcQy5-nQkoowqPHL4kMfeUslstNXljpzqSLmuECQNF8b_0SVoLzTCRlRXXMCr3-0CxBuxmOenve_eWXIT5PyOihYtx0LDGQBjHtIosfMRyh8VmTw8meVl-TIKyWPD0rKGKh8T76zJ0XxQVQsH0DmTnQkK9nXg_N_1yxp-xQl6X01hqN1-8f2mqg64TE9z5bn4llhFpuQwv_WFKYW2XjXH_PPL9CpraLYe_ezJ53Aevg0m1oiUg7paiGGjK-gdvkDtSpmmyEaJWU5z_FhJHR8ro-meI_FEzGYa4qWNXSyZvEOyY4hNHiS1AJb1u9znacA0oCeF9YLnhVllrcL6_28LXOU5CisxkVxw7ECi1X4IwcOiBlDnDAp8lPKd2rghwBfB-BwsNo_vIy1_xfN4SPli0ObCnSk96LMqVn5Mu3CKNM_6Wxt-Ht8SRt1KXUkSzQ6ffJabRLDYHgPOYMkBscMCrkRNLT6FesiemOtfTiBz4AsAk
and this is what comes out in the signature debug vs the nodejs api-sdk log
what i also spot is in the code for the GET request the payload has a bodyhash which i posted above^
Copy code
crypto.createHash("sha256").update(JSON.stringify(bodyJson || "")).digest().toString("hex")
and from testing this is never null, too, and this whole payload with the other params etc is part of the "body" in the biscuit.update
so I'm leaning towards that its impossible that the custsecret_1 got loaded properly
b
AslST2owWI56Akl2t0QYTLZCnsvqEUJyJV6oUVuyGbM
is a proper sha-256 hash
its unusual in that it looks like it uses base 64 encoding
but that checks out, all hashes will have the same length
Copy code
jsnBEBlcogkB2MHQmH2axqAKdK5splDXnrzZ_MHWaCeKqoX-kMorQzuEltUIuTM1PXFC_5ts9YqiWon7M4ye9fQ8l4xye9M4pXf_TqVAOsm9sJsYxDbEcyeZkNQ5A9mZfXwQ8JaFj6_a56ovEaupsQX2aa0AVVo0hihwnHAF0Ubn0MgnkEqQ6Ax2EWoJrPcQy5-nQkoowqPHL4kMfeUslstNXljpzqSLmuECQNF8b_0SVoLzTCRlRXXMCr3-0CxBuxmOenve_eWXIT5PyOihYtx0LDGQBjHtIosfMRyh8VmTw8meVl-TIKyWPD0rKGKh8T76zJ0XxQVQsH0DmTnQkK9nXg_N_1yxp-xQl6X01hqN1-8f2mqg64TE9z5bn4llhFpuQwv_WFKYW2XjXH_PPL9CpraLYe_ezJ53Aevg0m1oiUg7paiGGjK-gdvkDtSpmmyEaJWU5z_FhJHR8ro-meI_FEzGYa4qWNXSyZvEOyY4hNHiS1AJb1u9znacA0oCeF9YLnhVllrcL6_28LXOU5CisxkVxw7ECi1X4IwcOiBlDnDAp8lPKd2rghwBfB-BwsNo_vIy1_xfN4SPli0ObCnSk96LMqVn5Mu3CKNM_6Wxt-Ht8SRt1KXUkSzQ6ffJabRLDYHgPOYMkBscMCrkRNLT6FesiemOtfTiBz4AsAk
is far too large to have come out of a sha-256 hash
s
Copy code
jsnBEBlcogkB2MHQmH2axqAKdK5splDXnrzZ_MHWaCeKqoX-kMorQzuEltUIuTM1PXFC_5ts9YqiWon7M4ye9fQ8l4xye9M4pXf_TqVAOsm9sJsYxDbEcyeZkNQ5A9mZfXwQ8JaFj6_a56ovEaupsQX2aa0AVVo0hihwnHAF0Ubn0MgnkEqQ6Ax2EWoJrPcQy5-nQkoowqPHL4kMfeUslstNXljpzqSLmuECQNF8b_0SVoLzTCRlRXXMCr3-0CxBuxmOenve_eWXIT5PyOihYtx0LDGQBjHtIosfMRyh8VmTw8meVl-TIKyWPD0rKGKh8T76zJ0XxQVQsH0DmTnQkK9nXg_N_1yxp-xQl6X01hqN1-8f2mqg64TE9z5bn4llhFpuQwv_WFKYW2XjXH_PPL9CpraLYe_ezJ53Aevg0m1oiUg7paiGGjK-gdvkDtSpmmyEaJWU5z_FhJHR8ro-meI_FEzGYa4qWNXSyZvEOyY4hNHiS1AJb1u9znacA0oCeF9YLnhVllrcL6_28LXOU5CisxkVxw7ECi1X4IwcOiBlDnDAp8lPKd2rghwBfB-BwsNo_vIy1_xfN4SPli0ObCnSk96LMqVn5Mu3CKNM_6Wxt-Ht8SRt1KXUkSzQ6ffJabRLDYHgPOYMkBscMCrkRNLT6FesiemOtfTiBz4AsAk
and
AslST2owWI56Akl2t0QYTLZCnsvqEUJyJV6oUVuyGbM
is actually the signature after hmac that i'm comparing
which is why i'm feeling
Copy code
var biscuit = crypto.createHmac({
    algorithm: crypto.HashAlg.SHA256,
    key:rsa4096
 });

 biscuit.update({
    input:header +"."+ body,
    inputEncoding: encode.Encoding.UTF_8
 });

    var signature = biscuit.digest({
    outputEncoding:encode.Encoding.BASE_64_URL_SAFE
 })
biscuit loaded null from rsa4096 (which is the createSecretKey) and then digested fine
the jsnBEB i retrieved from the api-sdk js the actual signature and AS1ST is the signature output i got from NS
b
the output you are getting from the api is not a hash or hmac
its far too long
both hashes and hmac have a fixed length
s
@battk i was thinking in one case the hmac with key as param null, and the other with the key as some 3000 characters would elongate it and make the difference?
i mean the key is like 4kb as a text file with 3000 characters or so
b
the output of a hmac and hash is fixed in length
the secret key used in the hmac isnt actually limited in length, but in practical term it is
a secret key that is too long is just hashed before use so that its the right length
s
oh i see, ok i get you, which means in my code im missing something or some massaging or the likes
b
whatever you are working with is not the end product
it might be used in the middle, but certainly not the end
s
@battk i see, let me test, will keep you updated many thanks @battk!!!
b
which api are you trying to work with
s
Someone just raised my attention that creating a JWT example code is right there in the HTTPS module documentation https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4418229131.html
(see last section of that help page)
b
hs256 is hmac based, which is something that N/crypto will do
377 Views