How to decript password using nodejs or javascript - javascript

Tried to see my password from my database.My password is test123 So in my database i have saved like this : $2a$10$0V1JkVfl8n.WD/QbInIWqubjcaxnCCnP3K.bhuxjAQbJ9LyFiNTdu. How to see my password again like test123 from $2a$10$0V1JkVfl8n.WD/QbInIWqubjcaxnCCnP3K.bhuxjAQbJ9LyFiNTdu.
Can we do using nodejs or javascript?
var crypto = require("crypto");
var password = '$2a$10$0V1JkVfl8n.WD/QbInIWqubjcaxnCCnP3K.bhuxjAQbJ9LyFiNTdu';
var algorithm = "aes-192-cbc"; //algorithm to use
const key = crypto.scryptSync(password, 'salt', 24); //create key
var text = '?????????????????????????"; //text to be encrypted
const iv = Buffer.alloc(16, 0);
const cipher = crypto.createCipheriv(algorithm, key, iv);
var encrypted = cipher.update(text, 'utf8', 'hex') + cipher.final('hex'); // encrypted text
const decipher = crypto.createDecipheriv(algorithm, key, iv);
var decrypted = decipher.update(encrypted, 'hex', 'utf8') + decipher.final('utf8');
console.log(decrypted); //Output should be like test123

I don't believe it's meant to be decrypted on purpose.
"Cryptographic hash functions are a special type of one-way calculation"
What is hashing?
Cryptographic hash functions are a special type of one-way
calculation. They take a string of data of any size and always give an
output of a predetermined length. This output is called the hash, hash
value or message digest. Since these functions don’t use keys, the
result for a given input is always the same.
Encryption, hashing, salting – what’s the difference?
StackOverflow question:
"HMAC is a MAC/keyed hash, not a cipher. It's not designed to be
decrypted. If you want to encrypt something, use a cipher, like AES,
preferably in an authenticated mode like AES-GCM.
The only way to "decrypt" is guessing the whole input and then
comparing the output."
How can I decrypt a HMAC?

All these encrypting algorithms are trying NOT to do exactly what you are asking for :). It's a one way process. That means there is no well-known library in javascript or nodejs world to easily decrypt your password. Maybe there might be some applications, just using try-and-error method to guess your password.

It's not possible. Your password had the following functions applied.
Saved value = HASH(Password + salt)
That can't be undone.

Related

Converting PHP AES-256-CBC encryption into node.js

I have little to no knowledge in encryption and I've been facing issues trying to figure out how to convert these PHP functions to work with node.js and the crypto module.
function encryptAES($str,$key) {
$iv = "PJKKIOKDOICIVSPC"
$str = pkcs5_pad($str);
$encrypted = openssl_encrypt($str, "AES-256-CBC", $key, OPENSSL_ZERO_PADDING, $iv);
$encrypted = base64_decode($encrypted);
$encrypted = unpack('C*', ($encrypted));
$encrypted = byteArray2Hex($encrypted);
$encrypted = urlencode($encrypted);
return $encrypted;
}
function pkcs5_pad ($text) {
$blocksize = openssl_cipher_iv_length("AES-256-CBC");
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
function byteArray2Hex($byteArray) {
$chars = array_map("chr", $byteArray);
$bin = join($chars);
return bin2hex($bin);
}
Any help would be much appreciated.
Actually, porting issues without target code are routinely closed on SO. But in this case, a target code would not bring any particular benefit, because the main problem here is not porting, but an unnecessary complicated PHP code, which should be simplified first. This will make it almost a one-liner, which will also significantly simplify the porting:
The pkcs5_pad() function implements PKCS#7 padding, which is supported by PHP/OpenSSL out-of-the-box. However, the OPENSSL_ZERO_PADDING flag must be removed, as this disables padding. For completeness: PKCS#7 padding is often referred to as PKCS#5 padding in the Java world for historical reasons.
The explicit Base64 decoding of the ciphertext is not necessary. If the ciphertext should not be Base64 encoded, the implicit Base64 encoding can simply be disabled with the OPENSSL_RAW_DATA flag.
For the hex encoding of the ciphertext the unpack() call and the byteArray2Hex() method are not needed. Instead the ciphertext can be hex encoded directly with bin2hex().
A hex encoded ciphertext consists only of alphanumeric characters, so urlencode() does not change the result. Therefore this call can be omitted.
With this, your function can be simplified as follows:
function encryptAESsimple($str, $key){
$iv = "PJKKIOKDOICIVSPC";
$encrypted = openssl_encrypt($str, "AES-256-CBC", $key, OPENSSL_RAW_DATA, $iv);
return bin2hex($encrypted);
}
and pkcs5_pad() and byteArray2Hex() are obsolete.
Test:
The two calls
print(encryptAES("The quick brown fox jumps over the lazy dog", "01234567890123456789012345678901") . PHP_EOL);
print(encryptAESsimple("The quick brown fox jumps over the lazy dog", "01234567890123456789012345678901") . PHP_EOL);
return
59d97c5ae90a1ccf2c1d4ac10aebd2db2d4c1ebf743bbe748cb65bc2109aae43e9d7425cbe5b4d17e0324965cfb0db68
59d97c5ae90a1ccf2c1d4ac10aebd2db2d4c1ebf743bbe748cb65bc2109aae43e9d7425cbe5b4d17e0324965cfb0db68
and thus identical ciphertexts.
This simplification also makes NodeJS porting much easier. You can find some examples in the NodeJS documentation, for example:
var crypto = require('crypto')
var plaintext = Buffer.from('The quick brown fox jumps over the lazy dog', 'utf8');
var key = Buffer.from('01234567890123456789012345678901', 'utf8'); // Note: for a hex or base64 encoded key you have to change the encoding from utf8 to hex or base64
var iv = Buffer.from('PJKKIOKDOICIVSPC', 'utf8');
var cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
var ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
console.log(ciphertext.toString('hex')); // 59d97c5ae90a1ccf2c1d4ac10aebd2db2d4c1ebf743bbe748cb65bc2109aae43e9d7425cbe5b4d17e0324965cfb0db68
which gives the same ciphertext as the PHP code.
Security: The PHP code uses a static IV. This is insecure because it results in the reuse of key/IV pairs for a fixed key. Therefore, in practice, a random IV is generated for each encryption. This IV is not secret and is sent to the decrypting side along with the ciphertext, usually concatenated. The decrypting side separates both and performs the decryption.

Java and javascript generates different output for Base64 Hmac SHA256

When I tried to create similar function in Java and javascript which outputs a Base64 string of a Hmac SHA 256 encryption, the output given is not the same.
Javascript
var dataToSign = "message";
var secret = "secret";
function generateAuthHeader(dataToSign){
var hash = CryptoJS.HmacSHA256(dataToSign,secret);
return hash.toString(CryptoJS.enc.Base64);
which outputs
+eZuF5tnR65UEI+C+K3os8Jddv0wr95sOVgixTAZYWk=
Java
String key="secret";
String dataToSign = "message";
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
System.out.println(Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(dataToSign.getBytes("UTF-8"))));
which outputs
i19IcCmVwVmMVz2x4hhmqbgl1KeU0WnXBgoDYFeWNgs=
is there errors in my code?
What's the value of hash in the JavaScript version and what's the value of sha256_HMAC.doFinal(dataToSign.getBytes("UTF-8")) in the Java version?
Also, can you please try getting the Base64 repr in JavaScript:
CryptoJS.enc.Base64.stringify(hash);
instead of hash.toString ?
Also UTF-8 shouldn't make a difference in the Java version, but I'd try to remove those and simply do getBytes() everywhere.

CryptoJS not decrypting non-Latin characters faithfully

I am trying to use CryptoJS AES, like so:
var msg = "café";
var key = "something";
var c = CryptoJS.AES.encrypt(msg, key).toString();
CryptoJS.AES.decrypt(c, key).toString(CryptoJS.enc.Latin1);
Unfortunately this returns café, not café. Clearly Latin1 is not the right encoding to use, but I can't find a better one. Is there a solution?
Thanks.
You are just missing the format
The proper way is using CryptoJS.enc.Utf8
So, Please try:
CryptoJS.AES.decrypt(c, key).toString(CryptoJS.enc.Utf8);
https://code.google.com/p/crypto-js/#The_Hasher_Input
The hash algorithms accept either strings or instances of CryptoJS.lib.WordArray [...] an array of 32-bit words. When you pass a string, it's automatically converted to a WordArray encoded as UTF-8.
So, when you pass a string (and don't use CryptoJS.enc.* to generate a WordArray) it automatically converts the string (message) to a utf8 WordArray.
See here for sample roundtrip encrypt/decrypt:
https://code.google.com/p/crypto-js/#The_Cipher_Output
Here's a jsfiddle to play with CryptoJS
https://jsfiddle.net/8qbf4746/4/
var message = "café";
var key = "something";
var encrypted = CryptoJS.AES.encrypt(message, key);
//equivalent to CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(message), key);
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
$('#1').text("Encrypted: "+encrypted);
$('#2').text("Decrypted: "+decrypted.toString(CryptoJS.enc.Utf8));
To emphasize my point here is the same thing using Latin1 encoding:
https://jsfiddle.net/3a8tf48f/2/
var message = "café";
var key = "something";
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Latin1.parse(message), key);
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
$('#1').text("Encrypted: " + encrypted);
$('#2').text("Decrypted: " + decrypted.toString(CryptoJS.enc.Latin1));
On a side note, the API would probably be better if it only accepted WordArray and didn't overload the toString method (which is just a convenience interface to CryptoJS.enc.*.stringify). The string conversion magic is a little misleading.
You are trying to decrypt your data as a Latin1 string, even though your input string is not in Latin1. The encoding used by CryptoJS internally is not the same as the encoding you use to write the input file.
You need to specify the same encoding both when encrypting (for the string -> byte array conversion) and when decrypting (for the byte array -> string conversion).

How to convert to string and back again with CryptoJs

var encrypted = CryptoJS.AES.encrypt(jsonStr, 'youngunicornsrunfree', { format: JsonFormatter });
//convert encrypted to a string for transfer
//convert string back to Crypto object so it can be decrypted.
var decrypted = CryptoJS.AES.decrypt(encrypted, "youngunicornsrunfree", { format: JsonFormatter });
The above two steps, work fine. But in between I need to convert encrypted to a string for transmitting over a network and then convert it back. How can I do this?
Let's simplify this to be able to get to the problem. Firs we start with something like this:
jsonStr = '{"something":"else"}';
var encrypted = CryptoJS.AES.encrypt(jsonStr, 'youngunicornsrunfree');
var decrypted = CryptoJS.AES.decrypt(encrypted, "youngunicornsrunfree");
console.log(decrypted.toString(CryptoJS.enc.Utf8));
This gives us our answer jsonStr after we encrypt it then decrypt it. But say we want to send it to the server. We can do this easily by pulling out the encrypted string with toString(). Sounds to simple right? Say we need to send the encrypted jsonStr to the server. Try this
jsonStr = '{"something":"else"}';
var encrypted = CryptoJS.AES.encrypt(jsonStr, 'youngunicornsrunfree');
console.log("We send this: "+encrypted.toString());
Now say we sent something earlier and we are getting it back. We can do something like this:
var messageFromServer = "U2FsdGVkX19kyHo1s8+EwNuo/LQdL3RnSoDHU2ovA88RtyOs+PvpQ1UZssMNfflTemaMAwHDbnWagA8lQki5kQ==";
var decrypted = CryptoJS.AES.decrypt(messageFromServer, "youngunicornsrunfree");
console.log(decrypted.toString(CryptoJS.enc.Utf8));

What is DigestUtils sha256 encoding equivalent from JavaScript?

I call following and create the password hash.
ByteString password = ByteString.copyFrom(DigestUtils.sha256("mypassword"));
But now I need to send the sha256 converted password message from client (JavaScript). I tired to use CryptoJS as following
var pass = CryptoJS.SHA256(document.getElementById('password').value);
var passhash = pass.toString(CryptoJS.enc.Latin1)
login(passhash);
I tried all Base64, Latin1, and Hex types to get the string. But it will not produce the same password as the one in Java
Problem was with character encoding. Following fixed the problem.
in JS:
var password = pass.toString(CryptoJS.enc.Utf16);
In Java:
byte[] passhash = jsCryptoString.getBytes("UTF-16BE");

Categories

Resources