title: Understanding Dfinity's Identity Authentication in One Article#
date: 2021-08-16 14:02:50
Author: ddd009
This article starts with basic cryptographic concepts and explains the process of message signature authentication in detail. Finally, it explains how Dfinity uses the Internet Identity service to help users manage their own identities (keys).
Basic Concepts#
As you can see, in addition to the canister ID, function name, and other regular request information, the request content also includes the user's public key and message signature. The Caller's Principal is obtained by hashing the user's public key, and this process will be explained in detail later. After receiving the message, the callee will use the user's public key to verify the correctness of the signature and check if the public key corresponds to the Caller's Principal.
Canister developers do not need to worry about the underlying cryptographic details. They only need to write code, and Dfinity will automatically handle the identity authentication.
This image shows how to obtain the user's Principal from the public key.
Starting from the DER format public key, it is hashed using SHA-224, resulting in a 28-byte string. Then, one byte is added to distinguish the user principal from other principals, such as canister principals.
These 29 bytes represent the binary representation of the user principal. As you can see, the principal variables in Motoko and JS are Uint8 Blob arrays, which store these 29 bytes.
Next, these 29 bytes are converted into a textual representation. First, a CRC32 error check code is added, and then Base32 encoding is performed. The resulting string is grouped into groups of five characters, separated by "-", to obtain the textual representation of the user's principal.
By the way, there is a community implementation of base32 by flyq, which has been merged into the vessel-package-set and can be used through vessel.
If a user's principal is bound to a single key, it will be very inconvenient. If you have multiple devices, you need to use the same key on these devices, which is inconvenient and insecure.
Dfinity uses the mechanism of delegation keys. As shown in the figure, you can use the yellow key to sign the orange key and generate a delegation, which includes the scope and expiration time. The orange key can delegate to other keys, making this method very flexible.
By now, everyone should have a general understanding of basic concepts such as key pairs, user principals, and delegation keys. So how does Dfinity use these cryptographic techniques to complete user identity authentication?
Delegation Signature Authentication#
One application of delegation keys is related to Web Auth, which is the latest standard introduced by W3C for dual authentication in web applications. In addition to traditional usernames and passwords, users need to use additional security devices to sign the challenges sent by the server. The keys are stored in secure chips and will not be leaked. Even if your system is infected with malware, they cannot do anything to the keys in the secure chip. This way, it can be ensured that the user has logged in to the server.
The above is the practice of traditional internet. On Dfinity, this process is slightly different. When using a centralized server, you can establish a stateful long connection with the server, so you only need to sign the challenge sent by the server once, and the subsequent communication can be transmitted using the established connection. However, on Dfinity, there is no centralized server, and we cannot establish stateful connections between services. Services cannot actively send challenges to users. Therefore, users need to sign each request sent out. When using Web Auth, each signature needs to be confirmed. Of course, we cannot touch the Yubikey or fingerprint every time we send a request. Instead, we generate a short-term session key, use Web Auth to delegate sign the session key, and finally use the delegation key to automatically sign the message. This solves the problem of signing multiple messages.
Internet Identity#
Although Web Auth is very suitable for securely storing keys, due to security restrictions in browsers, the keys are bound to specific canisters. On the IC, different canisters are considered different origins, and this separation of states is crucial for security. However, this brings inconvenience to users. For example, it is difficult to use the same service across multiple devices. To address this drawback, the official introduced Internet Identity, abbreviated as II, which is similar to the SSO service "Sign With Google" and facilitates the management of keys and identities for users.
As shown in the figure, the application frontend generates a session key and sends the public key to the II service. If the user agrees, the II service will delegate sign the session key. All authentication processes are completed on the user's side.