- SSI란 자기주권 신원증명으로 오늘날의 ID 기술의 부족한 부분을 개선하기 위해 나온 기술로 기반 기술로는 블록체인이 사용됩니다.
SSI 기술과 오늘날의 ID 기술을 비교하여 어떤 점이 더 좋은지 알아보면, 오늘날의 신분증은 ID 시스템이 다르면 사용할 수 없거나 인증을 위해 비용이 소모됩니다.
예를 들어, 한국에서의 대학 졸업 여부를 해외 회사에 증명해야 한다고 하면 기존에는 한국 대학에서 졸업 증명서를 발급받고 이후 영문 공증까지 거쳐 제출해야 해외 회사에서 한국 대학의 졸업을 증명할 수 있었습니다.
이때 해외 회사는 받은 졸업증명서를 검증할 수 있지만, 자국의 졸업증명서를 검증하는것만큼 쉽지는 않을것 입니다. 영문 공증에 대한 진위 여부, 필요한 경우 언어가 다른 상대와 소통을 해야하는 등 자국의 졸업증명서와 다른 형식의 졸업증명에 대한 검증에 많은 비용과 시간을 소모해야합니다.
SSI 기술은 이러한 문제를 해결하기 위한 방법으로 블록체인 기술을 사용하고 있습니다. 블록체인의 가장 큰 장점 중 하나인 블록체인에 참여하는 모든 사람이 동일한 저장소를 신뢰성 있는 환경에서 소유할 수 있다는 것입니다.
예를 들어, 한국 대학과 미국 대학이 같은 블록체인 노드로 참여한 플랫폼에서 대학 졸업 여부를 증명한다고 가정할 경우, 해당 블록체인에 대학 졸업 증명 여부를 확인할 수 있는 값을 저장한 후 졸업 증명서를 관리 및 검증할 스마트 컨트랙트를 개발한다면 기존의 복잡한 과정없이 유동적으로 쉽게 졸업증명서를 검증할 수 있습니다.
- DID 및 DID Document : 각각 식별자와 인증 수단으로 사용됩니다.
- VC ( Verifiable Credential ) : 검증 가능한 자격증명으로 보관용 ID로 사용됩니다.
- VP ( Verifiable Presentation ) : 검증 가능한 제공 ID 데이터 집합으로 제출용 ID로 사용됩니다.
구성요소만 보아서는 잘 이해가 되지 않으니 하나씩 자세히 알아보도록 하겠습니다.
- 발행인 ( Issuer ) : VC를 발행하는 역할을 합니다. ( 신원 인증 기관 )
- 사용자 ( Holder ) : 발행인으로부터 VC를 발급 받은후 VP로 가공하여 검증 기관에 제출하는 역할을 합니다.
- 검증인 ( Verifier ) : 사용자로부터 VP를 수신하여 VP의 진위를 검증하는 역할을 합니다.
- 블록체인 ( BlockChain ) : DID 및 ID 관련 정보를 저장하는 분산 저장소 역할을 합니다.
DID는 기존의 중앙 기관을 통해 발급받고 통제되는 주민등록증, 운전면허증들과 다르게 사용하는 사람 스스로 생성하고 제어할 수 있는 분산형 식별자(탈중앙화 식별자) 입니다.
분산형 식별자란 단어가 처음봐서 헷갈릴 수 있습니다. 분산형 식별자란 사실 이미 통신에서 객체들을 식별하기 위해 UUID ( Universally Unique IDentifiers )라는 분산형 식별자가 많이 사용되고 있습니다.
이 분산형 식별자의 중요한 요소 중 하나가 동일한 식별자가 생성되지 않는 구조로 만드는 것인데, 중앙화된 식별자는 중앙기관이 알아서 동일한 식별자가 생성되지 않도록 만들어줄테지만, 탈중앙화 플랫폼에서는 각자가 식별자 간 충돌이 일어나지 않게 잘 생성해야 합니다. 충돌을 방지하기 위해 UUID는 아래와 같이 32개의 16진수와 4개의-
으로 이루어져 있습니다.
01234567-89ab-cdef-0123-456789abcdef
UUID가 랜덤하게 생성될 때 동일한 UUID가 생성될 확률은 2의 122승분의 1입니다. 전 세계 사용자들이 UUID를 생성하더라도 충돌을 걱정하지 않아도 되는 확률이니 동일한 식별자가 생성될 확률을 0에 가깝습니다.
DID도 UUID와 마찬가지로 생성 시 충돌을 걱정할 필요가 없습니다.
그렇다면 기존의 최근 각광받는 SSI기술의 DID는 UUID와 무엇이 다르기에 떠오르고 있는지 알아보자면,
UUID는 객체를 식별하는 식별자의 역할만 한다면 DID는 DID를 사용하는 객체에 대한 식별자로 사용될 뿐만 아니라 인증 수단인 DID document를 참조할 수 있는 URI 역할까지 수행합니다.
즉, DID는 DID document의 위치를 알 수 있는 주소인 것입니다.
DID는 아래의 같이 DID는 DID scheme, DID method, Method-specific identifier 3가지로 구성되어 있습니다.
did:ethr:0x123456789abcdefg
- DID scheme : URI가 어떤 프로토콜을 사용해서 자원에 접근하는지 명시합니다. URI scheme에는 우리가 흔히 사용하는 http, https를 포함한 다양한 프로토콜들이 정의되어 있는데, 만약 URI scheme에 did가 들어간다면 did scheme에서 정의한 자원 접근 방식에 따라 자원을 찾아가는것 입니다.
- DID method : DID document가 어떤 저장소에 저장되어 있는지 보여줍니다. 위에는 DID method에 ethr가 정의되어 있으므로 이더리움에 접근하여 DID document를 검색합니다.
- Method-specific identifier : DID method가 가르키는 저장소 내 DID document의 정확한 위치를 검색하기 위해서는 Method-specific identifier가 필요합니다.
이를 토대로 위의 DID 예시는 이더리움 블록체인에 접근한 후 Method-specific identifier를 이용해 검색하면 DID document를 가져올 수 있는것을 알 수 있습니다.
DID method가 지원하는 저장소로는 아래와 같은것들이 있습니다.
- btcr : Bitcoin
- ethr : Ethereum(uport)
- sov : Sovrin
- v1 : Veres One
- pid : IPFS
DID document에는 DID의 소유권을 증명할 수 있는 인증 수단이 포함되어 있습니다.
DID document에는 아래와 같이 @context, id, publicKey, authentication, service라는 5가지 중요 항목이 있습니다.
{ "@context": "https://www.w3.org/ns/did/v1", "id": "did:example:1234", "publicKey": [{ "id":"did:ethr:1234#keys-1", "type":"RsaVerificationKey2018", "controller":"did:ether:1234", "publicKeyPem":"---BEGIN PUBLIC KEY...END PUBLIC KEY-----/r/n" }, { "id":"did:ethr:1234#keys-2", "type":"Ieee2410VerificationKey2018", "controller":"did:ether:1234", "publicKeyPem":"---BEGIN PUBLIC KEY...END PUBLIC KEY-----/r/n" }], "authentication":["did:ethr:1234#keys-1","did:ethr:1234#keys-2"] "service":[{ "id":"did:ethr:1234#keyRotation", "type":"RotateUserKey", "serviceEndpoint":"https://example.com/keyrotation/" }] }
DID document에 id 항목에는 id를 통해 식별되는 객체의 DID가 들어갑니다. 만약 사용자를 식별하기 위한 DID document면 사용자의 DID가 들어갈 것이고 물건을 식별하기 위한 DID document면 물건의 DID가 들어갈 것입니다.
대게 DID document를 생성하고 등록한 사람의 DID가 id 항목에 들어갑니다.
publicKey와 authentication 항목은 DID 소유권 인증에 사용됩니다.
먼저 publicKey 항목에는 DID 소유권 인증에 필요한 다양한 종류의 데이터가 들어갈 수 있습니다.
위의 DID document 예시에는 소유권 인증에서 공개키와 개인키를 이용한 RSA 인증 방식과 생체 인증 방식을 사용할 수 있는 데이터가 있는것을 확인할 수 있습니다.
publicKey에는 4가지 세부 항목이 있는것을 알 수 있는데, 각각 어떤 역할을 하는지 알아보도록 하겠습니다.
- id : publicKey 내 사용할 수 있는 인증키의 위치를 나타냅니다. 예를 들어, 상대방에게 비대칭키 인증을 통해 소유권 인증을 하고 싶으면 id에 있는 DID를 알려주면서 소유권 인증 과정을 시작하면 됩니다.
- type : RSA 비대칭키 인증뿐 아니라 타원곡선, 생체 인증등 다양한 인증 방식이 들어갈 수 있습니다.
- publicKeyPem : 소유권 인증에 사용될 데이터가 저장되어 있습니다. 위와 같은 DID document에서 첫번째 인증방식은 RSA 비대칭키 인증 방식이기 때문에 공개키가 저장되어 있습니다.
- controller : publicKeyPem에 대한 인증 권한을 가진 사람이 누구인지 나타냅니다. 위와 같은 DID document에서는 RSA 비대칭키 인증 방식에 사용되는 공개키가 저장되어 있기 때문에 해당 공개키와 쌍을 이루는 비밀키를 가진 사람의 DID가 입력되있다고 이해하면 됩니다.
다음으로 authentication 항목에 관해 알아보도록 하겠습니다. authentication은 해당 DID document가 제공하는 소유권 인증 방식을 나타냅니다.
위와 같은 DID document의 authentication에 있는 DID 값은 publicKey에 있는 ID값들을 나타냅니다. 혹시 다른 방식의 인증도 추가한다면 publicKey에 인증 방식이 추가 될 것이고, authentication에도 해당 인증 방식의 ID값이 하나 추가 될 것입니다.
만약 인증 방식이 하나 추가되어 authentication에 DID 값이 하나 추가되었다면 이 DID document는 authentication안에 있는 세가지의 인증방식으로 DID의 소유권에 대한 인증을 수행할 수 있습니다.
Service 항목은 serviceEndpoint라는 세부 항목을 이용해 DID를 활용한 다양한 서비스를 개발 할 수 있습니다. 아래의 예시를 통해 자세히 설명하겠습니다.
{
... 중략
"id": "did:sov:1234",
"publicKey": {
"id":"did:sov:1234#keys-1",
"type":"RsaVerificationKey2018",
"controller":"did:sove:ABCD",
"publicKeyPem":"---BEGIN PUBLIC KEY...END PUBLIC KEY-----/r/n"
}
"authentication":["did:ethr:1234#keys-1"]
"service":[{
"id":"did:ethr:1234#keyRotation",
"type":"RotateUserKey",
"serviceEndpoint":"https://example.com/keyrotation/"
}]
}
A의 회사직원이 검증기관에 회사 A의 직원임을 인증하려는 상황이라고 예를 든다면 소유권 인증과정은 아래와 같이 진행될 것입니다.
- A회사 직원의 DID는 did:sov:1234이고 A회사의 DID는 did:sove:ABCD 입니다.
- 검증기관에게 A회사로부터 발급받은 DID를 보여주며 자신이 A회사 직원이라는것을 주장합니다.
- 검증기관은 받은 DID를 조회하여 DID document를 구해오고 authentication 항목을 확인하고 publicKey에 controller 항목을 확인하여 소유권 인증과정의 권한을 가진 DID에게 소유권 인증과정을 거칩니다. controller 항목에는 A회사에 DID가 들어가 있어 검증기관은 A회사에게 publicKeypem에 있는 공개키를 이용해 검증기관만 알고 있는 데이터를 암호화해서 A회사에게 전달며 해당 직원이 발급받은 DID가 정말 A회사가 발급한 DID가 맞는지 확인하고 맞다면 공개키와 쌍을 이루는 A회사가 가진 개인키를 사용하여 검증기관이 보낸 데이터를 해독한 후 값을 보내라고 합니다.
- A회사는 먼저 DID가 A회사에서 발급한 DID가 맞는지 DID 발급 기록을 확인하고 맞다면 A회사의 개인키를 가지고 암호화된 데이터를 해독한 값을 보냅니다.
- 마지막으로 검증기관에서 인증값을 확인한 후 DID Document 소유권에 대한 검증이 완료됩니다.
위와 같은 상황에서 A회사직원은 service 항목의 id에 있는 DID(
"id":"did:ethr:1234#keyRotation"
)를 검증기관에 보내 검증기관은 service 항목의 받은 DID와 일치하는 id를 찾은후 해당 service의 값을 확인한 후 A회사에 소유권 인증을 요청할 수 있었던 것입니다.
@context는 데이터가 어떤 값을 가지는지 명확한 정의를 해주는 역할을 합니다. 예를 들어, key값이 name이라고 하면 직관적으로 이름이 들어간다고 생각할 것입니다. 하지만 정확한 정의 없이 이렇게 직관적으로 정의를 하다보면 개발할 때 실수를 할 수 있습니다. 누구는 name의 value값을 '안수환123' 이런식으로 문자열과 숫자로 이루어진 데이터를 전송했다고 할 때, 수진자는 name의 value값을 문자열만 취급하도록 개발하였다면 두 컴퓨터간에 통신과정에서 에러가 발생할 것입니다. 이러한 이슈를 막기 위해 document에 어떤 key나 value값이 들어가는지 명확한 정의를 해주어야 하는데 이것을 해주는 속성이 @context입니다. @context는 JSON-LD 문법으로 이루어져 있기 때문에 아래에서 JSON-LD 문법을 살짝 알아보도록 하겠습니다.
JSON-LD의 @context 예제를 보고 설명하겠습니다.
{ "@context": { "name":"http://schema.org/name", "image":{ "@id":"http://schema.org./image", "@type":"@id" }, "homepage": { "@id":"http://schema.org/url", "@type":"@id" } }, "name":"AN SUHWAN", "image":"https://www.example.com/myImage", "homepage":"https://www.example.com" }
우선 @context에서 정의한 name의 value값에는
http://schema.org/name
이 들어간 것을 볼 수 있는데http://schema.org/name
는 key값에 많이 쓰이는 value값에 어떤 값들이 들어가는지 제공해주는 웹사이트입니다.
실제로 해당 사이트에 접속해보면 아래와 같이 schema.org 웹사이트에서 name에 대한 정의를 해준 내용이 있습니다.
다음으로 image의 @id부터 살펴보면 key로도 사용되었고, value로도 사용된 것을 확인할 수 있는데 각각의 용도가 있습니다. 우선 key로 사용될 때에는 IRI가 들어가야 한다는 뜻인데 IRI는 URI가 표현하는 문자열보다 다양한 인코딩이 가능합니다. 그래서 image의 @id에는 웹주소값인 IRI(http://schema.org/image
)가 들어간것을 확인할 수 있고, @type에는 value값으로 @id가 들어간것 확인할 수 있습니다. 위와 같이 @id가 value값으로 사용될 때에는 image단어에 그림파일이 위치한 IRI주소값을 입력해야한다는 의미입니다.
@ homepage도 image와 같은 방식으로 정의되어 있습니다.
위와 같이 @context를 직접 정의할 수도 있지만 정의할 양이 많은 경우 @context가 정의된 IRI주소를 입력할 수도 있습니다.
다음은 DID document에서 사용중인 공식 @context에 대한 내용을 갖는 IRI를 가진 @context를 정의한 모습입니다.{ "@context":"https://www.w3.org/ns/did/v1" }
이번에는 DID document에서 특정 항목만 선택해서 호출할 수 있는 DID dereference에 대해 알아보도록 하겠습니다.
- 대부분의 DID 플랫폼은 DID와 DID document 생성 시 비대칭키(개인키, 공개키)를 함께 생성합니다. 생성한 비대칭키의 개인키는 본인이 보관하고, 공개키는 DID document에 넣어서 블록체인에 저장합니다, 또한 DID의 생성 구조는 플랫폼마다 조금씩 다른데, Sorvin 블록체인의 DID는 비대칭키 생성시 공개키의 일부분이 Method-specific identifier가 됩니다. 정리하면 아래와 같은 구조가 될 것입니다.
did:sov:공개키
이더리움같은 경우에는 이더리움 어카운트 주소가 Method-specific identifier입니다. 정리하면 아래와 같은 구조가 될 것입니다.
did:ethr:지갑 주소
- 사용자 A가 DID와 DID document를 생성한 후, DID document는 DID method에 명시된 저장소에 저장합니다.
- 사용자 B가 사용자 A의 DID 주소를 안다면 DID에 명시된 저장소와 저장소 내 Method-specific identifier가 가리키는 위치에 저장된 사용자 A의 DID document를 획득할 수 있습니다.
위에 DID Document를 그대로 사용한다고 가정하고, 검증기관 역시 이미 사용자의 DID를 획득했다고 가정하겠습니다.
1. 검증기관은 사용자의 DID document의 authentication 항목을 확인하고 사용자의 DID 인증방식이 2가지가 있다는것을 확인하고 어떤 인증방식을 사용할 것인지 사용자에게 묻습니다.
2. 사용자는 publicKey 항목의 세부 id가 did:ethr:1234#keys-1 데이터를 사용해서 인증할 것이라고 응답을 보냅니다.
3. 사용자의 응답을 받은 검증기관은 DID document의 publicKey에서 응답받은 id와 일치하는 id를 찾아 해당 세부 항목에 있는 데이터를 이용하여 DID 소유권 검증 과정을 진행합니다.
4. 검증기관은 type에 명시된 비대칭키 암호화 방식대로 publicKeyPem에 있는 공개키를 이용해 검증기관만 알고 있는 데이터를 암호화해서 사용자에게 전송합니다.
5. 사용자는 자신만 알고있는 해당 공개키와 쌍을 이루는 개인키를 사용하여 검증기관이 보낸 데이터를 해독한 후 검증기관에게 결과값을 전송합니다.
6. 결과값을 받은 검증기관은 암호화에 사용한 데이터 값과 사용자에게 받은 결과값을 비교하여 사용자가 DID document의 주인이 맞는지 확인할 수 있습니다.