JSON 개체를 암호화하여 해시하려면 어떻게 해야 합니다.
다음 질문은 처음 보는 것보다 더 복잡합니다.
다른 중첩된 JSON 개체를 포함하여 임의의 양의 데이터를 포함할 수 있는 임의의 JSON 개체가 있다고 가정합니다.제가 원하는 것은 실제 JSON 포맷 자체에 관계없이 JSON 데이터의 암호화 해시/다이제스트입니다(예를 들어 줄 바꿈이나 JSON 토큰 간 간격 차이 무시).
마지막 부분은 요건입니다.JSON은 여러 플랫폼에서 다양한 (디)시리얼라이저에 의해 생성/읽어지기 때문입니다.역직렬화 중에 데이터를 읽을 때 포맷을 완전히 제거하는 Java용 JSON 라이브러리를 하나 이상 알고 있습니다.그렇게 하면 해시가 깨집니다.
위의 임의의 data 조항은 기존의 필드를 특정 순서로 가져와 해시하기 전에 연결하는 것을 방해하기 때문에 복잡합니다(Java의 비암호화 hashCode() 메서드가 어떻게 작동하는지 대략적으로 생각하십시오).
마지막으로 JSON 스트링 전체를 바이트의 청크로 해시하는 것(직렬화 해제 전)도 바람직하지 않습니다.JSON에는 해시 계산 시 무시해야 하는 필드가 있기 때문입니다.
이 문제에 대한 좋은 해결책이 있을지는 모르겠지만, 어떤 접근법이나 의견이라도 환영합니다 =)
이 문제는 유연성이 허용되는 모든 데이터 형식의 해시를 계산할 때 흔히 발생합니다.이 문제를 해결하려면 표현을 정규화해야 합니다.
예를 들어, 인증에 Twitter 및 기타 서비스에서 사용되는 OAuth1.0a 프로토콜은 요청 메시지의 안전한 해시가 필요합니다.해시를 계산하려면 OAuth1.0a에서 먼저 필드를 알파벳 순으로 정렬하고 줄 바꿈으로 구분한 다음 필드 이름(잘 알려진)을 삭제하고 빈 값에 빈 줄을 사용해야 한다고 합니다.시그니처 또는 해시는 정규화 결과에 따라 계산됩니다.
XML DSIG는 동일한 방식으로 작동합니다. 서명하기 전에 XML을 정규화해야 합니다.이것을 다루는 W3 규격이 제안되고 있는데, 그것은 서명을 위한 매우 기본적인 요건이기 때문입니다.어떤 사람들은 그것을 c14n이라고 부른다.
난 json의 표준 규격에 대해 몰라.조사해 볼 가치가 있어요.
없는 경우 특정 응용 프로그램 사용에 대한 규칙을 확실히 설정할 수 있습니다.적절한 시작은 다음과 같습니다.
- 이름순으로 속성을 정렬하다
- 모든 이름에 사용되는 큰따옴표
- 모든 문자열 값에 사용되는 큰따옴표
- 이름과 콜론 사이, 콜론과 값 사이에 공백 또는 원스페이스 없음
- 값과 다음 쉼표 사이에 공백이 없습니다.
- 다른 모든 공백이 단일 공백으로 축소되거나 공백이 없음 - 하나를 선택하십시오.
- 서명하지 않을 속성을 제외합니다(서명 자체를 보유하는 속성 등).
- 선택한 알고리즘으로 결과에 서명합니다.
또한 JSON 개체에서 시그니처를 전달하는 방법도 생각할 수 있습니다.아마도 "nichols-hmac"과 같은 잘 알려진 속성 이름을 설정하여 base64 인코딩된 버전의 해시를 가져올 수 있습니다.이 속성은 해시 알고리즘에서 명시적으로 제외해야 합니다.그러면 JSON의 모든 수신자가 해시를 확인할 수 있습니다.
정규화된 표현은 응용 프로그램에서 전달하는 표현일 필요는 없습니다.임의의 JSON 객체를 지정하면 쉽게 생성할 수 있습니다.
독자적인 JSON 정규화/표준화를 고안하는 대신 bencode를 사용하는 것이 좋습니다.의미적으로는 JSON(숫자, 문자열, 목록 및 딕트의 구성)과 동일하지만 암호화 해시에 필요한 모호하지 않은 인코딩의 특성을 가지고 있습니다.
bencode는 토렌트파일 형식으로 사용되며 모든 비트렌트클라이언트에는 구현이 포함되어 있습니다.
이는 S/MIME 시그니처 및 XML 시그니처에 관한 문제를 일으키는 것과 같은 문제입니다.즉, 서명할 데이터의 동등한 표현이 여러 개 존재합니다.
예를 들어 JSON의 경우:
{ "Name1": "Value1", "Name2": "Value2" }
대.
{
"Name1": "Value\u0031",
"Name2": "Value\u0032"
}
또, 애플리케이션에 따라서는, 다음과 같은 경우도 있습니다.
{
"Name1": "Value\u0031",
"Name2": "Value\u0032",
"Optional": null
}
표준화를 통해 이 문제를 해결할 수 있지만, 전혀 필요하지 않은 문제입니다.
규격을 제어할 수 있는 경우 개체를 일종의 컨테이너로 감싸 "동등"하지만 다른 표현으로 변환되지 않도록 보호하는 것이 가장 쉬운 해결책입니다.
즉, "논리적인" 객체에 서명하지 않고 대신 특정 연속 표현에 서명함으로써 문제를 방지합니다.
예를 들어 JSON Objects -> UTF-8 Text -> Bytes 입니다.바이트를 바이트로 서명한 다음 바이트로 전송합니다(예: base64 인코딩).바이트에 서명하기 때문에 공백과 같은 차이가 서명 내용에 포함됩니다.
이렇게 하는 것이 아니라:
{
"JSONContent": { "Name1": "Value1", "Name2": "Value2" },
"Signature": "asdflkajsdrliuejadceaageaetge="
}
다음 작업을 수행합니다.
{
"Base64JSONContent": "eyAgIk5hbWUxIjogIlZhbHVlMSIsICJOYW1lMiI6ICJWYWx1ZTIiIH0s",
"Signature": "asdflkajsdrliuejadceaageaetge="
}
즉, JSON에 서명하지 말고 인코딩된 JSON의 바이트에 서명합니다.
네, 서명이 더 이상 투명하지 않음을 의미합니다.
JSON-LD는 노멀라이제이션이 가능합니다.
컨텍스트를 정의해야 합니다.
RFC 7638: JSON Web Key(JWK) 지문에는 표준화의 종류가 포함되어 있습니다.RFC7638에서는 한정된 멤버세트를 상정하고 있습니다만, 어느 멤버에도 같은 계산을 적용할 수 있습니다.
https://www.rfc-editor.org/rfc/rfc7638#section-3
모든 필드를 지정된 순서대로(예를 들어 알파벳 순으로) 처리합니다.임의 데이터가 차이를 만드는 이유는 무엇입니까?속성(일명 반사)을 반복할 수 있습니다.
또는 raw json 문자열을 잘 정의된 표준 형식(모든 슈퍼플러스 포맷 제거)으로 변환하고 해시를 사용하는 것을 검토하겠습니다.
JSON 부호화 payload 해시에 간단한 문제가 발생했습니다.이 경우 다음 방법을 사용합니다.
- 데이터를 JSON 개체로 변환합니다.
- Base64에서 JSON 페이로드 인코딩
- 생성된 base64 페이로드 메시지 다이제스트(HMAC)
- base64 페이로드 전송
이 솔루션을 사용하는 장점:
- Base64는 특정 payload에 대해 동일한 출력을 생성합니다.
- 결과 시그니처는 base64로 인코딩된 페이로드에서 직접 파생되며 base64-payload는 엔드포인트 간에 교환되므로 시그니처와 페이로드가 유지됩니다.
- 특수문자 인코딩 차이로 발생하는 문제를 해결한 솔루션이다.
단점들
- payload의 부호화/복호화로 오버헤드가 추가될 수 있습니다.
- Base64 인코딩된 데이터는 보통 원래 페이로드보다 30 % 이상 커집니다.
이상적인 것은 JavaScript 자체가 JavaScript Objects에 대한 정식 해시 프로세스를 정의한 경우입니다.
그러나 RFC-8785 JSON 정규화 스킴(JCS)은 대부분의 Libs for JSON에서 구현이 가능하며 특히 인기 있는 JavaScript JSON 오브젝트에 추가할 수 있습니다.이 표준화를 완료하면 원하는 해시 알고리즘을 적용하기만 하면 됩니다.
JCS가 브라우저 및 기타 도구 및 lib에서 사용 가능한 경우 대부분의 JSON 온더와이어가 이 일반적인 정규화된 형식이 될 것으로 예상할 수 있습니다.이와 같은 표준의 공통적인 일관성 있는 적용과 검증은 저숙련 행위자의 사소한 보안 위협에 대한 반격으로 이어질 수 있습니다.
언급URL : https://stackoverflow.com/questions/4670494/how-to-cryptographically-hash-a-json-object
'it-source' 카테고리의 다른 글
Spring RestTemplate 요청에서 "Accept:" 헤더를 설정하려면 어떻게 해야 합니까? (0) | 2023.03.02 |
---|---|
Oracle: 행이 없는 경우 삽입하는 방법 (0) | 2023.03.02 |
반응 선택 테스트 방법(반응 선택) (0) | 2023.03.02 |
WooCommerce Webhooks Auth (비밀 & 시그니처) - 사용방법 (0) | 2023.03.02 |
사용자 목록 테이블에서 views_edit을 필터링하려면 어떻게 해야 합니까? (0) | 2023.03.02 |