Read the original article to learn more!
여러분은 JWT에 대해서 알고계신가요?
JWT(JSON 웹 토큰)는 데이터의 무결성을 검증하기 위해 서명된 JSON 객체로 당사자 간에 정보를 안전하게 전송하는 데 널리 사용됩니다. 일반적으로 사용되는 사용처는 인증 및 정보교환입니다. 여러분, 제가 새롭고 혁신적인 기술을 물고 왔습니다! 바로 SD-JWT(선택적 공개 JWT)인데요, SD-JWT는 개인정보 보호 및 선택적 정보 공유 계층을 추가한 기술입니다.
이게 대체 무슨 소리일까요? .... .사실 그렇게 어렵지 않습니다. 간단히 말하면 어떠한 정보를 숨길지,말지는 내가 결정한다. 라는 것입니다. 더 쉽게 말해 내 정보는 내가 지킨다. (Self-sovereign identity) 입니다. 이를 통해 JWT 보유자는 전체 토큰을 노출하지 않고 특정 정보만 검증인에게 공개할 수 있습니다. 특정 데이터만을 공유하는 시나리오에서 특히 유용할 것입니다.
JWT는 보안 통신을 위한 표준화된 방법을 제공하는 반면, SD-JWT는 향상된 개인정보 보호 제어 기능을 통해 이를 확장하여 선택적 데이터 공개가 필요한 상황에 매우 강력한 도구가 됩니다. 그럼 이쯤에서 궁금해질 것입니다.
JWT 의 경우, 보시는 것 처럼 32버전까지 나온 후에야 비로소 RFC 7519 버전이 확정이 됐습니다.
그에 반해 SD-JWT 는 아직 draft(초안, 확정되지 않은) 상태입니다. (Last updated - 2023-12-11) 표준 selective disclosure에 대한 요구는 있었지만 어떻게 구현할건지에 대한 확실한 표준이 없어서 각자 알아서 구현 했어야만 했습니다.
대부분의 경우, JWT 로 전송되는 정보를 굳이 선택적으로 숨길 이유가 없습니다.
굳이 선택적으로 숨길 이유가 없다........... 그렇다면 왜 SD-JWT를 사용해야 할까요?
사실 JWT와 SD-JWT는 사용처가 다른 개념일 뿐이지 뭐가 맞고 뭐가 틀린 것은 없습니다. SD-JWT 를 표준으로 정보를 교환해야 하면, 이에 맞추어서 구현을 해야하는 것 뿐입니다. (하지만 선택적으로 내 정보를 숨길 수 있다는 것은 정말 좋은 방법이라는 생각이 드네요.)
SD-JWT는 JWT 내의 클레임이 선택적으로 공개되도록 허용하는 동시에 이러한 클레임이 무단 수정되지 않도록 암호화하여 보호하는 방식으로 작동합니다.
사실 저는 여러분께 설명드리기 위해 해당 라이브러리를 깔아서 테스트를 해봤습니다.
1. sd-jwt 라이브러리를 install 합니다.
2. 사용할 SDJwt 인스턴스 생성합니다.
const { publicKey, privateKey } = await ES256.generateKeyPair();
// Create SDJwt instance for use
const sdjwt = new SDJwtInstance({
signer: await ES256.getSigner(privateKey),
verifier: await ES256.getVerifier(publicKey),
signAlg: "ES256",
hasher: digest,
hashAlg: "SHA-256",
saltGenerator: generateSalt,
});
3. claim(정보) 객체를 정의합니다.
// Issuer Define the claims object with the user's information
const claims = {
firstname: "John",
lastname: "Doe",
ssn: "123-45-6789",
id: "1234",
data: {
firstname: "John",
lastname: "Doe",
ssn: "123-45-6789",
list: [{ r: "1" }, "b", "c"],
},
data2: {
hi: "bye",
},
};
4. 숨길 정보를 지정합니다.
const disclosureFrame: DisclosureFrame<typeof claims> = {
_sd: ["firstname", "id", "data2"],
data: {
_sd: ["list"],
_sd_decoy: 2,
list: {
_sd: [0, 2],
_sd_decoy: 1,
0: {
_sd: ["r"],
},
},
},
data2: {
_sd: ["hi"],
},
};
5. 발급해봅니다.
const credential = await sdjwt.issue(claims, disclosureFrame);
credentail 을 콘솔에 찍어보면 'ifQ.PIo17-SQBrp0LtOhu5JUdSiCrFgv9zwdG7PfRYM..1' 와 같은 encode된 토큰이 찍힐 것입니다. 발급이 완료 되었습니다.
6. decode 함수를 실행시켜 credential을 decode 해봅니다. 어떻게 나올까요 ?
const sdJwtToken = await sdjwt.decode(credential);
이처럼 숨겨진 정보와 disclosures된 정보들을 확인 할 수 있습니다.
7.frame과 발급한 credentail을 넣고 present 함수를 실행시켜봅니다.
const presentationFrame = ["firstname", "id"];
const presentation = await sdjwt.present(credential, presentationFrame);
presentationFrame에 공개하고 싶은 정보만을 요소로 넣어주면 됩니다. presentation 결과 또한 'eyJhbGciOiJFUz..' 와 같은 해당 토큰이 발급되는데요,이 토큰을 풀어보면 presentationFrame에 넣은 값들을 포함한 요소를 보여줄 수 있습니다.
4번에 제가 강조했던 것 처럼 정보를 숨겼던 것이 아닙니다.
숨길것인지 드러낼 것인지에 대한 정보들을 지정했기 때문에 숨길지, 말지를 내 스스로 정할 수 있게 된 것입니다.
이로써 내 정보에 대한 주권을 내가 가지게 되었습니다! 😉
저는 해당 라이브러리를 사용하면서 디버깅 사이트를 이용해 디버깅을 진행했습니다.
제가 만든 학습 사이트도 함께 이용해보세요.
결론적으로 SD-JWT는 정보의 선택적 공개를 가능하게 함으로써 디지털 거래의 신뢰성을 유지할 뿐만 아니라 혁신적으로 개인정보를 보호합니다. 요즘엔 다양한 분야에서 SD-JWT 사용을 채택함으로써 민감한 정보를 보호할 수 있는 잠재력을 입증하고 있다고 하네요.
SD-JWT의 주요 키워드는
딱 이거 하나입니다. 이것만 기억하시면 됩니다.
이 글은 곧 성지가 될 것입니다. :D
https://www.youtube.com/watch?v=gov5ohxjSWI
https://vertex.beehiiv.com/p/enhancing-privacy-digital-transactions-rise-sdjwt
https://www.youtube.com/watch?v=fo5JxPszCqY
https://www.ietf.org/archive/id/draft-fett-oauth-selective-disclosure-jwt-02.html
https://darutk.medium.com/oid4vci-demo-87a232cfcc2a
성지순례 왔습니다. 리 - 턴