I am using the crypto module in NetSuite SuiteScript 2.0 . I am using the createHmac method in crypto like below
var hmacSignature = crypto.createHmac({
algorithm: crypto.HashAlg.SHA1 ,
key: sKey
});
I am getting a invalid Type Argument for 'algorithm' value. This is the specified way to set the type as given on NetSuite SuiteScript PDF. What am I doing wrong??
Thanks to Krypton , I could solve this problem by passing a crypto.SecretKey object by generating it using crypto.CreateSecretKey method
Related
I can successfully create an Hmac via NodeJS using the following code:
(slightly altered example from : https://nodejs.org/api/crypto.html#cryptocreatehmacalgorithm-key-options)
Crypto.createHmac('sha256', Crypto.randomBytes(16))
.update('I love cupcakes')
.digest('hex');
That results in a value like the following (hex-based string Hmac signature):
fb2937ca821264812d511d68ae06a643915931375633173ba64af9425f2ffd53
How do I use that signature to verify that the data was not altered? (using NodeJS, of course).
My Assumption
I'm assuming there is a method call where you supply the data and the signature and you get a boolean that tells you if the data was altered or not -- or something similar.
Another Solution?
Oh, wait, as I was writing that I started thinking...
Do I need to store the original random bytes I generated (Crypto.randomBytes(16)) and pass them to the receiver so they can just generate the HMac again and verify that the result is the same (fb2937ca821264812d511d68ae06a643915931375633173ba64af9425f2ffd53)?
If that is true that would be odd, because the parameter for Crypto.randomBytes(16) is named secret (in the official example)*. Seems like that needs to be kept secret??
Please let me know if there is a way to verify the signature on the receiving side & how I do that.
Official Documentation : A Bit Confusing
Here's the function as it is defined in the official docs:
crypto.createHmac(algorithm, key[, options])
In the function definition, you can see the second param is named key.
However, in the example they refer to it as secret
const secret = 'abcdefg';
const hash = crypto.createHmac('sha256', secret)
.update('I love cupcakes')
.digest('hex');
console.log(hash);
Just posting the answer so if anyone in future sees this they will be able to have the definitive answer.
As the commentor (Topaco) pointed out, the simple answer is that:
The receiver who want wants to validate the Hmac simply needs to use the same key value & data and apply it to the method and retrieve the hash value.
const secret = 'abcdefg';
const hash = crypto.createHmac('sha256', secret)
.update('I love cupcakes')
.digest('hex');
console.log(hash);
The original Hmac-creating party must provide three things for the verifying party:
data : (could be encrypted data from AES256, for example)
key : original key passed into the createHmac() method -- note: this item is called secret in the sample code by NodeJS (above).
hash :the (clearText) hash which the original creator generated when calling the createHmac() method.
With those three things the verifying party can now call the createHmac() method and determine if the hash they get matches the hash that the original hmac-creating party generated.
Doing this validates that the Data which was sent has not been corrupted or altered.
Additional Note On Key (secret)
I've come back after thinking about the Hmac a bit more.
It is required that both parties know the key (aka secret) but it does not mean that it should be exposed to others.
This must be kept secret (as the code implies) because if a nefarious type knew the value and could alter it, then they could also alter the data and generate a new key (secret) and pass it along as if the original creator sent it along (MITM - man in the middle attack).
So, the point here is that yes, both parties have to know the key (secret) value, but it should not be shared where it might be discovered by nefarious types.
Instead, it will have to be agreed upon or based upon a secret password, etc.
I have a swift project with 3 entities in my xcdatamodeld: Access, CustomerInfo and User. I am trying to save the dateEndSubscription separately in the User. When I am trying to save , I get error as : Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: the entity User is not key value coding-compliant for the key "dateEndSubscription".' Anyone please help to solve it in swift4.
The json message contains the key dateEndSubscription but the attribute in your User entity is named dateEnd so they doesn’t match.
A few options to solve this in your saveUser method
Change API.DateEnd to dateEnd but maybe that will infer with the decoding of the json message.
Don't use API key but instead hardcode attribute name
user.setValue(dateEnd, forKey: "dateEnd")
and lastly use the property of the User class directly
user.dateEnd = dateEnd
You need to change saveCustomerInformation as well since you are working with a User object there as well although it's unclear why.
in Python Pycryptodome default example for DSA-DSS
Hi guys.I asked this question but , it's not clever , I deleted on my profile and just asking from my friends account.
Problem is that .I tried to use public key encryption , signature , verifiying , so..
Till tomorrow all's going well but I encounter with DSA-DSS ECDSA. If you look at picture , I think there some issue that I target it.They makes "signer" with private key in DSS , but they don't uses it in signature. Instead it using key sign .Even at verifying level , (in picture didn't appear) they call public key from "PEM" file and trying to verify without call DSS new() again..
So if you compare my code and picture then you notice actually what I want to say...
from Crypto.PublicKey import DSA
from Crypto.Signature import DSS
from Crypto.Hash import SHA256
key = DSA.generate(2048)
publickey=key.publickey()
message = b"Hello"
hash_obj = SHA256.new(message)
signer = DSS.new(key, 'fips-186-3')
signature = signer.sign(hash_obj)
So here I trying to verify message..I did't create has object again,and I called public key from key that I showed it above.
pkey=DSS.new(publickey,'fips-186-3')
pkey.verify(hash_obj,signature)
False
So as you can see , I got "False" .I tried it on ECDSA - DSS returned samething again.
so if you got what I want to do , please help , what I want to to?
The docs for the verify method say:
Raises: ValueError – if the signature is not authentic
and it always return False if it is successful.
So rather than checking the return value, you need to check if the method raises an exception.
In general you will want something like:
try:
pkey.verify(hash_obj,signature)
valid = True
except ValueError:
valid = False
In your code the fact that it doesn’t raise an exception shows that the verification has succeeded and the signature is in fact valid.
Goal: Convert JS Date Object to a String representation in the format of "11/2/2017" in a NetSuite SuiteScript 2.0 scheduled script.
I have a date object that I need to use for 2 purposes. In one, I am going to use it for comparisons (so I want the actual date object). The other is I want it to be the name of a Custom Record, ie a string value.
I am doing this in NetSuite SuiteScript 2.0 (Javascript) in a Scheduled Script. The toString() of the date right now is: "2017-11-02T07:00:00.000Z". The format I want to end up with for the name is 11/2/2017.
When I test toLocaleDateString() in a browser test app, I get 11/2/2017 - the exact format I want. However, when I sue this same thing in SuiteScript 2.0 I get "November 2, 2017". I know there is a difference between client/server but this was frustrating.
I tried the format.parse() function as NetSuite's documentation claims that this is the equivalent to the 1.0 nlapiDateToString() function. This did not work.
Besides writing my own function (which I am tempted to do), does anyone know how to accomplish this goal?
To switch over to that format you would not use format.parse, you would use format.format. Here is a simple example of converting a date object to that string format.
require(['N/format'],function(format){
function formatDate(testDate){
log.debug('testDate: '+testDate);
var responseDate=format.format({value:testDate,type:format.Type.DATE});
log.debug('responseDate: '+responseDate);
}
var testDate=new Date();
formatDate(testDate);
});
I'm going to suggest using the momentJS library for all of your SuiteScript date manipulation needs. It works well as a SuiteScript 2.0 module and you can format dates easily:
var now = new Date();
var formattedDate = moment(now).format('M/D/YYYY');
Use format.parse module of suitescript 2.0
var myDateString= "04/26/2020";
var parseDate = format.parse({
value: myDateString,
type: format.Type.DATE
});
Hello I have this Java code which uses the following encryption method to encrypt password.
MessageDigest digester = MessageDigest.getInstance("SHA-1");
value = digester.digest(password.getBytes());
digester.update(email.getBytes());
value = digester.digest(value);
This returns base64 encoded string like qXO4aUUUyiue6arrcLAio+TBNwQ= This is sample not exact.
I am converting this to NodeJs not sure how to handle this. I have tried like
var crypto = require('crypto');
var shasum = crypto.createHash('sha1');
var value = shasum.update('hello');
shasum.update('abc#xyz.com');
value = shasum.digest(value).toString('base64');
console.log(value);
The string base64 I get in node js is not similar to get from java. Not sure why?. I need to have same encoding as java as its old system migrated to new one cant lose old details.
Can someone help me how I can achieve same base64 string.
In Java you're calculating the first value as the hash of the password alone, then overwrite it with hash of the email alone. (digest gives the result and resets the hash, in Java).
In Javascript, on the other hand, you're having an undefined value, then overwrite it with the hash of (password concatenated with email).
PS that hash is conceptually wrong: you should always put a separator between two fields, to avoid ambiguity and, thus, possible attacks.