How to generate a base64 encoded, SHA-512 hash in Appcelerator? - base64

Have been trying this for 2 days but failed miserably. We are using appcelerator 5.1.0.
I'm able to hash a string using the module Securely . However the result string is in hex format and i need it to be in base64 encoded string.
Tried the Ti.Utils.base64encode function but the result doesn't match what is generated at the backend. Here's my code snippet:
function convertHexToBase64(hexStr){
console.log("hex: "+hexStr);
var hexArray = hexStr
.replace(/\r|\n/g, "")
.replace(/([\da-fA-F]{2}) ?/g, "0x$1 ")
.replace(/ +$/, "")
.split(" ");
var byteString = String.fromCharCode.apply(null, hexArray);
var base64String = Ti.Utils.base64encode(byteString).toString();
console.log("base64 string:"+base64String);
return base64String;
}
Tried to find other modules to use and the node's Buffer is the closest i can get but am not sure how to use a node class in appcelerator...
Anyone can shed a light or two? Thanks.

Finally did it with the help of Forge, putting the steps here for future reference
Create a folder under the lib folder, named it forge
Install the module to local machine (via node), copy the whole contents of the js folder into the forge folder.
In the code, create the object:
var forge = require('forge/forge');
Hash the string first to get a buffer object, then encode it to base64 string.
var md = forge.md.sha512.create();
md.update(saltedText);
var buffer = md.digest();
result = forge.util.encode64(buffer.getBytes());

Related

How to compare filenames with difference in special character encoding?

I am working with a system that syncs files between two vendors. The tooling is written in Javascript and does a transformation on file names before sending it to the destination. I am trying to fix a bug in it that is failing to properly compare file names between the origin and destination.
The script uses the file name to check if it's on destination
For example:
The following file name contains a special character that has different encoding between source and destination.
source: Chinchón.jpg // hex code: ó
destination : Chinchón.jpg // hex code: 0xf3
The function that does the transformation is:
export const normalizeText = (text:string) => text
.normalize('NFC')
.replace(/\p{Diacritic}/gu, "")
.replace(/\u{2019}/gu, "'")
.replace(/\u{ff1a}/gu, ":")
.trim()
and the comparison is happening just like the following:
const array1 = ['Chinchón.jpg'];
console.log(array1.includes('Chinchón.jpg')); // false
Do I reverse the transformation before comparing? what's the best way to do that?
If i got your question right:
// prepare dictionary
const rawDictionary = ['Chinchón.jpg']
const dictionary = rawDictionary.map(x => normalizeText(x))
...
const rawComparant = 'Chinchón.jpg'
const comparant = normalizeText(rawComparant)
console.log(rawSources.includes(comparant))

the output of "crypto.createCipheriv with chinese character" is not correct

when there is no chinese character, php and node output the same result.
but when this is chinese character, the output of php is correct, the output of node is not correct
const crypto = require('crypto');
function encodeDesECB(textToEncode, keyString) {
var key = new Buffer(keyString.substring(0, 8), 'utf8');
var cipher = crypto.createCipheriv('des-ecb', key, '');
cipher.setAutoPadding(true);
var c = cipher.update(textToEncode, 'utf8', 'base64');
c += cipher.final('base64');
return c;
}
console.log(encodeDesECB(`{"key":"test"}`, 'MIGfMA0G'))
console.log(encodeDesECB(`{"key":"测试"}`, 'MIGfMA0G'))
node output
6RQdIBxccCUFE+cXPODJzg==
6RQdIBxccCWXTmivfit9AOfoJRziuDf4
php output
6RQdIBxccCUFE+cXPODJzg==
6RQdIBxccCXFCRVbubGaolfSr4q5iUgw
The problem is not the encryption, but a different JSON serialization of the plaintext.
In the PHP code, json_encode() converts the characters as a Unicode escape sequence, i.e. the encoding returns {"key":"\u6d4b\u8bd5"}. In the NodeJS code, however, {"key": "测试"} is applied.
This means that different plaintexts are encrypted in the end. Therefore, for the same ciphertext, a byte-level identical plaintext must be used.
If Unicode escape sequences are to be applied in the NodeJS code (as in the PHP code), an appropriate conversion is necessary. For this the jsesc package can be used:
const jsesc = require('jsesc');
...
console.log(encodeDesECB(jsesc(`{\"key\":\"测试\"}`, {'lowercaseHex': true}), 'MIGfMA0G')); // 6RQdIBxccCXFCRVbubGaolfSr4q5iUgw
now returns the result of the posted PHP code.
If the Unicode characters are to be used unmasked in the PHP code (as in the NodeJS code), an appropriate conversion is necessary. For this the flag JSON_UNESCAPED_UNICODE can be set in json_encode():
$data = json_encode($data, JSON_UNESCAPED_UNICODE); // 6RQdIBxccCWXTmivfit9AOfoJRziuDf4
now returns the result of the posted NodeJS code.

Groovy - how to Decode a base 64 string and save it to a pdf/doc in local directory

Question
I need help with decoding a base 64 string and saving it to a pdf/doc in local directory using groovy
This script should work in SOAP UI
The base64 string is 52854 characters long
I have tried the following
File f = new File("c:\\document1.doc")
FileOutputStream out = null
byte[] b1 = Base64.decodeBase64(base64doccontent);
out = new FileOutputStream(f)
try {
out.write(b1)
} finally {
out.close()
}
But - it gives me below error
No signature of method: static org.apache.commons.codec.binary.Base64.decodeBase64() is applicable for argument types: (java.lang.String) values: [base64stringlong] Possible solutions: decodeBase64([B), encodeBase64([B), encodeBase64([B, boolean)
Assuming the base64 encoded text is coming from a file, a minimal example for soapUI would be:
import com.itextpdf.text.*
import com.itextpdf.text.pdf.PdfWriter;
String encodedContents = new File('/path/to/file/base64Encoded.txt')
.getText('UTF-8')
byte[] b1 = encodedContents.decodeBase64();
// Save as a text file
new File('/path/to/file/base64Decoded.txt').withOutputStream {
it.write b1
}
// Or, save as a PDF
def document = new Document()
PdfWriter.getInstance(document,
new FileOutputStream('/path/to/file/base64Decoded.pdf'))
document.open()
document.add(new Paragraph(new String(b1)))
document.close()
The File.withOutputStream method will ensure the stream is closed when the closure returns.
Or, to convert the byte array to a PDF, I used iText. I dropped itextpdf-5.5.13.jar in soapUI's bin/ext directory and restarted and then it was available for Groovy.

Trouble in decoding the Path of the Blob file in Azure Search

I have set a Azure search for blob storage and since the path of the file is a key property it is encoded to Base 64 format.
While searching the Index, I need to decode the path and display it in the front end. But when I try to do that in few of the scenarios it throws error.
int mod4 = base64EncodedData.Length % 4;
if (mod4 > 0)
{
base64EncodedData += new string('=', 4 - mod4);
}
var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
return System.Text.Encoding.ASCII.GetString(base64EncodedBytes);
Please let me know what is the correct way to do it.
Thanks.
Refer to Base64Encode and Base64Decode mapping functions - the encoding details are documented there.
In particular, if you're using .NET, you should use HttpServerUtility.UrlTokenDecode method with UTF-8 encoding, not ASCII.

Calculating sha1 in Node.js returns different result than in PHP

I'm calculating SHA1 using the following PHP code:
$hash = base64_encode(sha1($password.$key, true).$key);
But when I do this in Node.js, it does not give me the same result:
var hash = crypto.createHash('sha1').update(password + key).digest('base64');
Why are the results different?
In your PHP code, you're appending the key to the sha1 before passing it to base64:
sha1($password.$key, true).$key
In order to replicate that in Node.js, you'll need to do the same:
var hash = crypto.createHash('sha1').update(password + key).digest('hex');
var result = new Buffer(hash + key).toString('base64');
Edit: after looking at the PHP docs on sha1, it looks like the second parameter being passed to sha1 is going to return non-hex data:
If the optional raw_output is set to TRUE, then the sha1 digest is instead returned in raw binary format with a length of 20, otherwise the returned value is a 40-character hexadecimal number.
So in order for the two snippets to function the same, you'd also need to modify the PHP to not pass that parameter:
$hash = base64_encode(sha1($password.$key).$key);
You need to append key in the nodejs:
// php
$hash = base64_encode(sha1($password.$key, true).$key);
// see this ^^^^
// node
var hash = crypto.createHash('sha1').update(password + key).digest('base64') + key;
// add this ^^^^^^

Resources