programing

JavaScript 개체를 안정적으로 해시하는 방법

topblog 2023. 2. 27. 23:20
반응형

JavaScript 개체를 안정적으로 해시하는 방법

신뢰할 수 있는 방법은 없을까?JSON.stringifyJavaScript 객체가 동일한 경우 결합 JSON 문자열이 모든 브라우저, Node.js 등에서 동일함을 보증하는 JavaScript 객체.

JavaScript 객체를 해시하고 싶다.

{
  signed_data: object_to_sign,
  signature:   md5(JSON.stringify(object_to_sign) + secret_code)
}

웹 애플리케이션(예: Python 및 Node.js)과 사용자에게 전달하여 사용자가 한 서비스에 대해 인증하고 해당 서비스에 대한 다음 서비스 "서명된 데이터"를 표시하여 데이터가 진짜인지 확인할 수 있습니다.

그런데 갑자기 문제가 생겼어요.JSON.stringify는, 실장 전체에서 일의는 아닙니다.

  • Node.js/V8에서는JSON.stringify는 불필요한 공백 없이 JSON 문자열을 반환합니다(예: '{"user_id":3}).
  • 파이썬의simplejson.dumps여백이 남습니다.'{"user_id": 3}'
  • 아마 다른 문자열화 구현에서는 공백, 속성 순서 등의 처리가 다를 수 있습니다.

신뢰할 수 있는 크로스 플랫폼 문자열화 방법이 있습니까?"Nomalized JSON"이 있습니까?

이와 같은 객체를 해시하는 다른 방법을 추천해 주시겠습니까?

갱신:

회피책으로 사용하는 것은 다음과 같습니다.

normalised_json_data = JSON.stringify(object_to_sign)
{
  signed_data: normalised_json_data,
  signature:   md5(normalised_json_data + secret_code)
}

따라서 이 접근법에서는 객체 자체가 아니라 JSON 표현(시그닝 플랫폼 고유)이 서명됩니다.이게 잘 되는 이유는 제가 지금 서명하고 있는 것은 명확한 문자열이기 때문입니다.JSON.parse시그니처 해시를 확인한 후 데이터.

여기서 단점은 만약 내가 전체를 보낸다면{signed_data, signature}JSON으로서도 반대합니다.전화를 걸어야 합니다.JSON.parse내부가 빠져나갔기 때문에 보기에도 좋지 않습니다.

{"signature": "1c3763890298f5711c8b2ea4eb4c8833", "signed_data": "{\"user_id\":5}"}

npm 패키지 오브젝트 해시에 관심이 있을 수 있습니다.오브젝트 해시는 액티비티와 신뢰성 레벨이 상당히 좋은 것 같습니다.

var hash = require('object-hash');

var testobj1 = {a: 1, b: 2};
var testobj2 = {b: 2, a: 1};
var testobj3 = {b: 2, a: "1"};

console.log(hash(testobj1)); // 214e9967a58b9eb94f4348d001233ab1b8b67a17
console.log(hash(testobj2)); // 214e9967a58b9eb94f4348d001233ab1b8b67a17
console.log(hash(testobj3)); // 4a575d3a96675c37ddcebabd8a1fea40bc19e862

이것은 오래된 질문이지만, 구글 심판들을 위해 이 질문에 대한 최신 해결책을 추가하려고 합니다.

현재 JSON 개체에 서명 및 해시하는 가장 좋은 방법은 JSON토큰을 사용하는 것입니다.이를 통해 개체에 서명, 해시 및 서명을 기반으로 다른 개체에 의한 검증을 수행할 수 있습니다.다양한 테크놀로지용으로 제공되고 있으며, 활발한 개발 그룹이 있습니다.

여러 언어에 걸친 구현이 동일해야 합니다.운이 없으시군요두 가지 옵션이 있습니다.

  • www.json.org 의 실장을 체크하고, 보다 표준화 되어 있는지를 확인합니다.
  • 각 언어로 독자적인 롤업(json.org의 실장을 기반으로 하고 있기 때문에 할 일이 거의 없습니다)

할 수 .stringify()하다

  • 불필요한 여백을 삭제하다
  • 해시 내의 속성 이름 정렬
  • 명확한 일관된 인용 스타일
  • 문자열 내용을 정규화한다('\u0041'과 'A'가 동일해진다).

그러면 오브젝트의 표준 JSON 표현이 남습니다.이러한 표현은 신뢰성 있게 해시할 수 있습니다.

해시 알고리즘과 JSON-to-string 메서드를 사용해 본 결과, 이것이 최적인 것을 알았습니다(죄송합니다만, 타이프 스크립트입니다만, 물론 javascript로 고쳐 쓸 수 있습니다).

// From: https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key
function sortObjectKeys(obj){
    if(obj == null || obj == undefined){
        return obj;
    }
    if(typeof obj != 'object'){ // it is a primitive: number/string (in an array)
        return obj;
    }
    return Object.keys(obj).sort().reduce((acc,key)=>{
        if (Array.isArray(obj[key])){
            acc[key]=obj[key].map(sortObjectKeys);
        }
        else if (typeof obj[key] === 'object'){
            acc[key]=sortObjectKeys(obj[key]);
        }
        else{
            acc[key]=obj[key];
        }
        return acc;
    },{});
}
let xxhash64_ObjectToUniqueStringNoWhiteSpace = function(Obj : any)
{
    let SortedObject : any = sortObjectKeys(Obj);
    let jsonstring = JSON.stringify(SortedObject, function(k, v) { return v === undefined ? "undef" : v; });

    // Remove all whitespace
    let jsonstringNoWhitespace :string = jsonstring.replace(/\s+/g, '');

    let JSONBuffer: Buffer = Buffer.from(jsonstringNoWhitespace,'binary');   // encoding: encoding to use, optional.  Default is 'utf8'
    return xxhash.hash64(JSONBuffer, 0xCAFEBABE, "hex");
}

npm 모듈(https://cyan4973.github.io/xxHash/ 및 https://www.npmjs.com/package/xxhash)을 사용했습니다.

이점:

  • 이것은 결정론적이다.
  • 키 순서를 무시합니다(어레이 순서 유지).
  • 크로스 플랫폼(JSON-stringify와 동등한 것을 찾을 수 있는 경우) JSON-stringify는 다른 구현을 얻지 못할 것이며 공백 공간을 삭제함으로써 JSON 포맷이 독립적이 될 것입니다.
  • 64비트
  • 결과 16진수 문자열
  • 최고 속도(2177B JSON의 경우 0.021밀리초, 150kB JSON의 경우 2.64밀리초)

필요에 따라 Bencode가 준비되어 있을 수 있습니다.크로스 플랫폼이며, 모든 구현에서 인코딩이 동일함을 보증합니다.

불란하다> > > Bools > Bools > Bools > Bools > Bools > Bools > Bools > Bools > Bools > Bools > Bools > Bools > Bools > Bools >와 같은 작업을 수 .0|1nulls -> > > > > >"null"부호화 전.

언급URL : https://stackoverflow.com/questions/5559712/how-to-reliably-hash-javascript-objects

반응형