B
B
BulaevInc2021-08-08 06:20:51
JavaScript
BulaevInc, 2021-08-08 06:20:51

How to port object from JS to other languages?

In general, straight to the point
. There is such a code:

for (var i = CryptoJS.SHA512("hello"), n = 0; n < 10; n++) {
    i = CryptoJS.SHA512(i);
}

It's not difficult to understand what it does: each new iteration hashes the hash of the previous .. hash.
And if CryptoJS.SHA512("hello") returns the correct hash of the "hello" string, then i = CryptoJS.SHA512(i) already hashes not the hello string, but the CryptoJS object instance. And such a method was used in a string that I would like to find using not JavaScript, but for example C ++.
Now I will explain in more detail:
Here is the JS code that I have already shown wrapped in a function:
function encodeManyTimes(str){
for (var i = CryptoJS.SHA512(str), n = 0; n < 5; n++) {
    console.log(i.toString()); 
    i = CryptoJS.SHA512(i);
    }
}

encodeManyTimes("hello")


And this is what it outputs:
9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
0592a10584ffabf96539f3d780d776828c67da1ab5b169e9e8aed838aaecc9ed36d49ff1423c55f019e050c66c6324f53588be88894fef4dcffdb74b98e2b200
6d9f8ed2218b64d92f5e09788f29c56e3a7c3ff7bd5b2677b452ac1e3e5f9cbacf0f67cb9e27da424b4d3c325c27e5a6f8b563ae26972e47f0bfe4012f0474fe
a530df680b53b3f1ddd68947a3af8c686d59f7df65642e40d4ef65512dd295f58d50c4040d51ca3c5af43055d9b2ff4aca7bdba5bef077a92568554b50174d3f
5ab743e5b9704b2ae1584c7b768aba17d98388c1cb56b7c7240a0636157e21251ecb636baff93da58db7ea849c1f8717649a6963162ee8fe66fc9b391a2aa94c


Here is the "same" algorithm implemented in C++:
void encodeManyTimes(std::string str){
       std::string i = CryptoC.SHA512(str);
       for(int n = 0; n < 5; n++){
         std::cout << i << std::endl;
         i = CryptoC.SHA512(str);
       }
    }

int main(){
encodeManyTimes("hello");
return 0;
}


And the output is this:
9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
66c6a0830f3e5e4460d3ff64a23705e600e5d369ad3bda4a77ae9c0328115b813c2f7e6354add00cbad31c758bb9a122e4a4d84d52741b113908e8d735a9ac79
f48b46195cf8a8fbe2797a04a28c49e4d4f1c1aabfd6e96ca78133435c295096e03e1be39a42b4abe4505d22cef0646aad3f4012c408aae9dfc218cc90a67138
bff6d385a80adeda27cd26537d7abb54a26b39a1772f0b5d1fc5c8f2a46105464fe0d75765ad565da3181933231037ab93d2416ca1c6df2e25cf63c688d39f11
5f4b0c5db1bb5c26af9ce41fdbc1716120a5155c2d2b365f464e610bebc62ef34f2c487a87fae04952b9b2bd50c9b24fdd8b31a5fc6739893bf9597c31eeb4e2


Well, I'll formulate the question more broadly: how can I ensure that the result of the code executed in C ++ is identical to the result of the code executed in JS WITHOUT touching the JS code?
Maybe there is a method by which you can somehow find out in what form CryptoJS accepts an instance of an object of itself and what it hashes to repeat this method using other tools?

Z.s, this is what I get if I output the i instance (from the first code) in one of the iterations in console.log, but no matter how I fight, I can’t turn it into a hash by other means than JS
console log(i)
{
  init: [Function (anonymous)],
  '$super': {
    init: [Function: init],
    toString: [Function: toString],
    concat: [Function: concat],
    clamp: [Function: clamp],
    clone: [Function: clone],
    random: [Function: random],
    '$super': {
      extend: [Function: extend],
      create: [Function: create],
      init: [Function: init],
      mixIn: [Function: mixIn],
      clone: [Function: clone]
    }
  },
  words: [
      93495557,  2231348217,
    1698296791,  2161604226,
    2355616282,  3048303081,
    3903772728,  2867644909,
     919904241,  1111250416,
    4729098438,  1818436853,
     898154120,  2303717197,
    3489511243, -1729973760
  ],
  sigBytes: 64
}

Answer the question

In order to leave comments, you need to log in

6 answer(s)
G
GrayHorse, 2021-08-09
@BulaevInc

in what form does CryptoJS take an instance of an object of itself and what does it hash to repeat this method using other tools

All cryptographic algorithms work with bytes. CryptoJS uses an abstraction in the form of the "WordArray" class to represent bytes, because this is an old library written when there was no "ArrayBuffer".
I need it to DO NOT WORK the same way as it DOES NOT WORK in js,

It is working. And rightly so.
Do you really think I can move in time and space to a programmer who once hashed a word with this method and tell him "hey, you're hashing an object, don't, hash a string" and give him this code?

To which that programmer would respond: "Don't talk nonsense."
And he will be right.
Because in his case, the program takes bytes from the string and hashes them, then hashes them again, and so on:
SHA512(
        SHA512(
                SHA512("hello".getBytes()) 
        )
).toString("hex");

For output to the console, it presents them as a hex string.
---
Hashes from the output of the alleged C++ program:
SHA512(
        SHA512(
                SHA512("hello".getBytes()).toString("hex").getBytes()
        ).toString("hex").getBytes()
).toString("hex");

Doesn't bother you? What is considered here is not the same.
---
to repeat this method using other tools

Other tools in the form of Java:
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.*;

public class Main {
    public static void main(String[] args) throws NoSuchAlgorithmException {
        byte[] bytesOfMessage = "hello".getBytes(StandardCharsets.UTF_8);
        MessageDigest SHA512 = MessageDigest.getInstance("SHA512");

        byte[] digest = SHA512.digest(bytesOfMessage);
        Main.log(digest);
        for (int i = 0; i < 4; i++) {
            digest = SHA512.digest(digest);
            Main.log(digest);
        }
    }
    private static void log(byte[] digest) {
        var hex = new BigInteger(1, digest).toString(16);
        if (hex.length() % 2 == 1) {
            hex = "0" + hex;
        }
        System.out.println(hex);
    }
}

Shock! The output is the same for the "wrong" CryptoJS. Banking apps are in danger!
---
Theme is krinzh.

D
DollyPapper, 2021-08-08
@DollyPapper

And if CryptoJS.SHA512("hello") returns the correct hash of the "hello" string, then i = CryptoJS.SHA512(i) already hashes not the hello string, but the CryptoJS object instance.

Well, I will formulate the question more broadly: how can I ensure that the result of the code executed in C ++ is identical to the result of the code executed in JS?

- No way. If each new iteration hashes not a string, but an object, then the result in js and crosses will be different, because they hash different things. If you want to achieve the same result, hash not an object, but a string.

S
shurshur, 2021-08-09
@shurshur

It is impossible to do this without touching the crooked implementation in js already in advance. Alas. The hash may generally depend on the js engine and its version, on the hardware and software platform, since the structure of the object is not the same in different implementations, which can give different end results.
Theoretically, if the latter is overcome, that is, an unequal result in different conditions (by running the code in predictably identical ones), then, for example, you can design a hashing microservice that will receive data and hash them according to a crooked algorithm. But it would be better, of course, not to suffer from this garbage, but to fix the original problem. It's like diseases of genetic origin: it is almost impossible to treat them, because a person already has billions of incorrect copies of DNA in the body, which are too late to correct.

D
Developer, 2021-08-08
@samodum

At each iteration, it is necessary to hash not an object, but a hash obtained at the previous iteration, a string.
Then there will be no difference in languages

P
profesor08, 2021-08-08
@profesor08

In your C++ CryptoC.SHA512(str) returns a hex string. In js CryptoJS.SHA512(str) takes a string but returns an object. And then you shove an object into it again. And wonder why it doesn't work.

const hash = async (str) => {
  const msgUint8 = new TextEncoder().encode(str);
  const hashBuffer = await crypto.subtle.digest("SHA-512", msgUint8);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  const hashHex = hashArray.map(b => b.toString(16).padStart(2, "0")).join("");
  return hashHex;
}

U
Uno, 2021-08-09
@Noizefan

What does "no matter how I fight" mean?)
we take the bible, we read how it is formed

words: [
      93495557,  2231348217,
    1698296791,  2161604226,
    2355616282,  3048303081,
    3903772728,  2867644909,
     919904241,  1111250416,
    4729098438,  1818436853,
     898154120,  2303717197,
    3489511243, -1729973760
  ],
  sigBytes: 64

the rest does not seem to change.
We do the same on the crosses and everything works.
Instead of wasting time explaining your question to people here, it would be more efficient to spend time studying the bible.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question