CryptoJS weird encrypt/decrypt failure - cryptojs

I just want to encrypt a 128 bit code using AES-128 but it results in weird decrypt result.
It is set up this way so it can represent my real implementation:
var plain = CryptoJS.lib.WordArray.random(128/8);
console.log("plain: " + plain.toString(CryptoJS.enc.Base64));
var iv_wordArr = CryptoJS.lib.WordArray.random(128/8);
var salt = CryptoJS.lib.WordArray.random(128/8);
var key128Bits = CryptoJS.PBKDF2("12345678", salt, { keySize: 128/32, iterations: 1000 });
var encrypted = CryptoJS.AES.encrypt(plain.toString(CryptoJS.enc.Base64), key128Bits, { iv: iv_wordArr });
var dbKeyEnc = iv_wordArr.toString(CryptoJS.enc.Base64) + ":" + encrypted.toString();
salt = salt.toString(CryptoJS.enc.Base64);
var splitted = dbKeyEnc.split(":");
key128Bits = CryptoJS.PBKDF2("12345678", CryptoJS.enc.Base64.parse(salt), { keySize: 128/32, iterations: 1000 });
iv_wordArr = CryptoJS.enc.Base64.parse(splitted[0]);
var decrypt = CryptoJS.AES.decrypt(splitted[1], key128Bits, { iv: iv_wordArr });
console.log("decrypt: " + decrypt.toString(CryptoJS.enc.Base64));
//console error: Invalid array length (because of decrypt wrong result)
I have checked step by step and iv, salt, key are alright. Problem comes when decrypting.

After extense testing I found out that the problem was with the salt.
I assumed that this functions did the same thing:
var salt = CryptoJS.lib.WordArray.random(128/8);
salt = salt.toString(CryptoJS.enc.Base64);
salt = CryptoJS.enc.Base64.stringify(salt); //correct one
But they are different. The second one is the one that keeps the same value.

Related

Simple Edit check to email out person not working

When someone puts a Y in a cell on a sheet it emails someone.
I am getting it no matter what I enter for the check: Y, F, T, bob - it ALWAYS emails out regardless of the value. It's like the IF is just setting whatever I am asking it to check to the value and doing it. Never seen this in the years of programming..
Can anyone see see something I am missing? I am using an edit trigger
function Checkchange() {
var POs=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(11, 2).getValue();
var rec=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(31, 2).getValue();
var backorder=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(37,5).getValue();
var buyer=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(38,2).getValue();
var QA=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(41,5).getValue();
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(58, 3).setValue(POs)
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(60, 3).setValue(rec)
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(61, 3).setValue(backorder)
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(62, 3).setValue(buyer)
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(63, 3).setValue(QA)
sendEmailsRec();
}
function sendEmailsRec() {
var EMAIL_SENT = 'EMAIL_SENT';
var QAemailAddress = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(60, 1).getValue();
var POs = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(11, 2).getValue();
var message = "Ready for receiving for PO " + POs;
var QAcheckbox = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(31,2).getValue()
var subject = "Ready for receiving for PO" + POs;
var check = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(60, 4).getValue() + QAcheckbox
// if(QAcheckbox ="Y",MailApp.sendEmail(QAemailAddress, subject, message));
if(QAcheckbox ==="hdjkheehehie",
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(60, 3).setValue(EMAIL_SENT)+
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(65, 3).setValue(QAemailAddress + subject + message)+
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(60, 4).setValue(check));
}
Your condition has a wrong logical operator. One = will always return true. Use == or === instead:
if (QAcheckbox == "Y"){
MailApp.sendEmail(QAemailAddress, subject, message));// Always triggers regradless of value
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(63, 3).setValue(EMAIL_SENT));
}
You can read more about operators here.

how to set hash in Postman Pre-Request Script for Marvel API

I have a pre-request script that I gathered from another post on StackOverflow, but I'm still getting invalid credentials.
Attempted to do this just with str_1 but it's not working. Not sure what request.data is supposed to do as it keeps returning NaN. I think that the problem might be there, but still at a loss. I've attempted converting all variables to a string, but that still returned the same error.
URL = https://gateway.marvel.com/v1/public/characters?ts={{timeStamp}}&apikey={{apiKey}}&hash={{hash}}
// Access your env variables like this
var ts = new Date();
ts = ts.getUTCMilliseconds();
var str_1 = ts + environment.apiKey + environment.privateKey;
// Or get your request parameters
var str_2 = request.data["timeStamp"] + request.data["apiKey"];
console.log('str_2 = ' + str_2);
// Use the CryptoJS
var hash = CryptoJS.MD5(str_1).toString();
// Set the new environment variable
pm.environment.set('timeStamp', ts);
pm.environment.set('hash', hash);
{
"code": "InvalidCredentials",
"message": "That hash, timestamp and key combination is invalid."
}
If someone can comment on why this is the solution, I would appreciate it. Here is what the issue was. The order of the hash actually matters. So had to flip the order of pvtkey + pubkey to pubkey + pvtkey. Why is this?
INCORRECT
var message = ts+pubkey+pvtkey;
var a = CryptoJS.MD5(message);
pm.environment.set("hash", a.toString());
CORRECT
var message = ts+pvtkey+pubkey;
var a = CryptoJS.MD5(message);
pm.environment.set("hash", a.toString());
I created in Android Studio, a new java class named MD5Hash, following the steps of https://javarevisited.blogspot.com/2013/03/generate-md5-hash-in-java-string-byte-array-example-tutorial.html
I just simplified his (her) code, only to use it with Java utility MessageDigest
public class MD5Hash {
public static void main(String args[]) {
String publickey = "abcdef"; //your api key
String privatekey = "123456"; //your private key
Calendar calendar=Calendar.getInstance();
String stringToHash = calendar
.getTimeInMillis()+ privatekey + publickey;
System.out.println("hash : " + md5Java(stringToHash));
System.out.println("ts : "+ calendar.getTimeInMillis());
}
public static String md5Java(String message){
String digest = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hash = md.digest(message.getBytes("UTF-8"));
//converting byte array to Hexadecimal String
StringBuilder sb = new StringBuilder(2*hash.length);
for(byte b : hash){
sb.append(String.format("%02x", b&0xff));
}
digest = sb.toString();
} catch (UnsupportedEncodingException ex) {
} catch (NoSuchAlgorithmException ex) {
}
return digest;
}
}
As you can see, if you copy paste this code, it has a green arrow on the left side of the class declaration, clicking it you can run MD5Hash.main() and you'll have printed in your Run Screen the values for the time (ts) and for the hash.
Then go to verify directly into the internet :
https://gateway.marvel.com/v1/public/characters?limit=20&ts=1574945782067&apikey=abcdef&hash=4bbb5dtf899th5132hjj66

Reimplementation of an old c++ project that uses SHA2 in nodejs?

I've to convert an old c++ project in nodejs. That project relies in sha2 (polarssl) to do some cryptography. I tried to do this using crypto but I failed since the outputs are completely different.
//here i declare 2 keys
unsigned char key1[] = {0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F};
unsigned char key2[] = {0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC};
sha2_context sha_ctx;
// Part 1: Compute the key with key1 and key 2
sha2_starts( &sha_ctx, 0 );
sha2_update( &sha_ctx, key1, sizeof(key1) );
sha2_update( &sha_ctx, key2, sizeof(key2) );
sha2_finish( &sha_ctx, digest );
// Part 2: The HMAC SHA-2 HMAC start
sha2_hmac_starts( &sha_ctx, digest, 32, 0 );
// SHA-2 Update
sha2_hmac_update( &sha_ctx, buffer, 16 );
// SHA-2 Finish
sha2_hmac_finish( &sha_ctx, digest );
Here's my attempts:
Using crypto HMAC (I tried it even if I thought it was not the correct way)
var {key1, key2, key_expected, key_expected_hex} = common;
// They use http://asf.atmel.com/docs/latest/uc3c/html/sha2_8h.html
function test(){
var hmac = crypto.createHmac('SHA256', new Buffer([0x00]))
hmac.update(key1);
hmac.update(key2);
var r = hmac.digest('hex');
console.log({
output: r,
expected: key_expected_hex
})
return r === key_expected_hex;
}
Using npm 'sha2' library
const {SHA256} = require("sha2");
function test(){
var hmac = SHA256(key1);
hmac = SHA256(key2);
console.log(hmac);
var r = hmac.toString('hex');;
console.log({
output: r,
expected: key_expected_hex
})
return r === key_expected_hex;
}
Can someone help me out pointing me in the right direction?
In node.js the Part 1 consisting of computing the key for the hmac used in Part 2, should not use hmac but only sha256 as in the C++ code :
const crypto = require('crypto');
const key1 = new Buffer([0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F]);
const key2 = new Buffer([0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC]);
// Part 1: Compute the key from key1 and key2
var h = crypto.createHash('sha256');
h.update(key1);
h.update(key2);
var keyForHmac = h.digest();
console.log('key: ' + keyForHmac.toString('hex'));
// Part 2: The HMAC SHA-256
var buffer = new Buffer([/* data to be HMACed */]);
var hmac = crypto.createHmac('sha256', keyForHmac);
hmac.update(buffer);
var hmacDigest = hmac.digest();
console.log('hmac: ' + hmacDigest.toString('hex'));

google-apps-script multiple criteria writing over headers

I have taken a bit of script from Serge which is great (original link here. I have added in a second criteria to exclude certain rows and it works great except, if there is not header in the sheet being copied to, it will not work (error: "The coordinates or dimensions of the range are invalid.") and if I enter a header or some other data, it overwrites it. Can anyone assist please? I have also found that is there is no match to the criteria I get following message "TypeError: Cannot read property "length" from undefined."
Also, what change would I need to make to change the cell 'dataSheetLog[i][12]' to the status variable, i.e. "COPIED" after I have copied it across. I have tried writing a setValue line but it is obviously the wrong instruction for that syntax.
Code is:
{
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheetLog = Spreadsheet.getSheetByName("LOG");
var sheetMaint = Spreadsheet.getSheetByName("MAINTENANCE");
var Alast = sheetLog.getLastRow();
var criteria = "08 - Maintenance"
var status = "COPIED"
var dataSheetLog = sheetLog.getRange(2,1,Alast,sheetLog.getLastColumn()).getValues();
var outData = [];
for (var i in dataSheetLog) {
if (dataSheetLog[i][2]==criteria && dataSheetLog[i][12]!=status){
outData.push(dataSheetLog[i]);
}
}
sheetMaint.getRange(sheetMaint.getLastRow(),1,outData.length,outData[0].length).setValues(outData);
}
In:
sheetMaint.getRange(sheetMaint.getLastRow(),1,outData.length,outData[0].length).setValues(outData);
getLastRow() refers to the last occupied row and should be ,getLastRow() + 1,to keep from overwriting your headers and other problems.
Edited:
{
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheetLog = Spreadsheet.getSheetByName("LOG");
var sheetMaint = Spreadsheet.getSheetByName("MAINTENANCE");
var Alast = sheetLog.getLastRow(); // Log
var criteria = "08 - Maintenance"
var status = "COPIED"
var dataSheetLog = sheetLog.getRange(2,1,Alast,sheetLog.getLastColumn()).getValues(); //Log
var dataSheetLogStatusRange = sheetLog.getRange(2,13,Alast,1); //Log
var dataSheetLogStatus = dataSheetLogStatusRange.getValues(); //Log
var outData = [];
for (var i =0; i < dataSheetLog.length; i++) {
if (dataSheetLog[i][2]==criteria && dataSheetLog[i][12]!=status){
outData.push(dataSheetLog[i]);
dataSheetLogStatus[i][0] = "COPIED";
}
}
if(outData.length > 0) {
sheetMaint.getRange(sheetMaint.getLastRow() + 1,1,outData.length,outData[0].length).setValues(outData);
dataSheetLogStatusRange.setValues(dataSheetLogStatus);
}
}
}
what change would I need to make to change the cell
'dataSheetLog[i][12]' to the status variable, i.e. "COPIED" after I
have copied it across.
You were trying to update the value in the array that was extracted from the sheet and not the sheet itself. As arrays are zero based and spreadsheets are not, to translate, +1 must be added to array row and column indices. I am assuming status is in column M of your sheet.

URLEncode variable Parsing from String to Array as3

Ok! I have a flashVar variable that is coming into Flash, its URL encoded but I have already decoded it. My problem is I want the set of variables to be pushed into an array.
Let's say the variables are
"&text0=Enter Text...&size0=18&font0=Arial&color0=0&rotation0=0&y0=360&x0=640&text1=Enter
Text...&size1=18&font1=Arial&color1=0&rotation1=0&y1=360&x1=640"
and so on...
What I want is the variables to go into an array like
myArray[0].text = Enter Text...
myArray[0].size = 18]
myArray[0].font = Arial
myArray[0].color = 0
myArray[0].rotation = 0
myArray[0].y = 360
myArray[0].x = 640
myArray[1].text = ...........
.............................
.............................
myArray[n].text = ...........
I think there must be some way to do this. Most probably I'm thinking regular expression, but I'm pretty bad at regular expression. Please some help would be very very appreciated.
Thank You!
You don't have to decode your query string, just use the URLVariables object - it will do all the decoding for you. Then iterate over its dynamic properties to create your array. Use a RegExp to find the index numbers at the end of your variable keys:
function parseURLVariables( query:String ) : Array {
var vars:URLVariables = new URLVariables (query);
var arr:Array = [];
for (var key : String in vars) {
var splitIndex : int = key.search(/[0-9]+$/);
var name:String = key.substr (0,splitIndex);
var indexNumber:int = parseInt ( key.substr(splitIndex));
arr[indexNumber] ||= {};
arr[indexNumber][name] = vars[key];
}
return arr;
}
Since your query string starts with a an ampersand, you might have to use parseURLVariables ( myString.substr(1)), otherwise the URLVariables object will throw an error, complaining that the query string is not valid (it has to be url encoded, and start with a variable key).
you may use split method of string to something like this;
var astrKeyValue: Array = url.Split( "&" );
in this way each value in astrKeyValue is string keyvalue ( for example font1=Arial )
after than you may split each item with "=" and will get pair key and value ( for key - font1 and for value - arial)
so this code maybe will work for you
var str = "text0=Enter Text...&size0=18&font0=Arial&color0=0&rotation0=0&y0=360&x0=640&text1=Enter Text...&size1=18&font1=Arial&color1=0&rotation1=0&y1=360&x1=640"
var a : Array = str.split( "&" );
var newArr: Array = new Array()
for each ( var str1 in a )
{
var t: Array = str1.split( "=" );
newArr[ t[0] ] = t[1];
}
trace( newArr.text0 ) // -> Enter Text...
Here is a solution for you from me,
//your string data should be like this, there should be a seperate seperator (i've used pipe sign |) for each element which will be converted to an object and then pushed to the array
var strData:String = "text=Enter Text...&size=18&font=Arial&color=0&rotation=0&y=360&x=640|text=Enter Text...&size=18&font=Arial&color=0&rotation=0&y=360&x=640";
var myArray:Array = new Array();
var _tmpArr:Array = strData.split("|");
//populating the array
for(var i:int=0;i<_tmpArr.length;i++)
{
myArray.push(strToObj(_tmpArr[i]));
}
trace(myArray.length);
// coverts chunk of string to object with all key and value in it
function strToObj(str:String):Object
{
var obj:Object = new Object();
var tmpArr:Array = str.split('&');
for (var i:int = 0; i < tmpArr.length; i++)
{
var _arr:Array = String(tmpArr[i]).split('=');
var key:String = String(_arr[0]);
var val:String = String(_arr[1]);
obj[key] = val;
trace(key+" = "+val);
}
trace("----");
return obj;
}