JavaScript 개체를 안정적으로 해시하는 방법
신뢰할 수 있는 방법은 없을까?JSON.stringify
JavaScript 객체가 동일한 경우 결합 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|1
nulls -> > > > > >"null"
부호화 전.
언급URL : https://stackoverflow.com/questions/5559712/how-to-reliably-hash-javascript-objects
'programing' 카테고리의 다른 글
Woocommerce용 ionic 앱에서 PayPal 결제는 어떻게 처리합니까? (0) | 2023.02.27 |
---|---|
각도 UI 선택 : 원격 서비스에서 데이터 가져오기 (0) | 2023.02.27 |
Oracle이 존재하지 않는 테이블 또는 뷰를 알려주지 않는 이유는 무엇입니까? (0) | 2023.02.27 |
DataTable을 다시 초기화할 수 없음 - 데이터 테이블의 동적 데이터 (0) | 2023.02.27 |
WordPress가 IN() 조건으로 준비한 문 (0) | 2023.02.27 |