This proposal outlines a signing mechanism which allows an applications to request a user's authentication or to ask a user to agree with an agreement, such as
Terms of Service in a secure way. In the traditional web structure, the authentication breaks down into two micro steps:
- Identification: The ability to identify uniquely a user of a system or an application that is running in the system.
- Authentication: The ability to prove that a user or application is genuinely who that person or what that application claims to be.
In the decentralized blockchain world, the process is totally different. The user, as the private key holder, has a unique way to identify and authenticate themselves. In this senario, the term Certificate is more precise than Credential.
agreementcan be select now. It may expand in the future. When an application is requesting the user's signature, it needs to declare its purpose; the user needs to check the content before signing.
object: The body of the payload
- type -
string: Specify the type of content, currently it only support
typemay be extended in the future.
- content -
string: A message for user which is determine by
type. When the type is "text", it should be text format.
- type -
second, consistent with UNIX timestamp and block timestamp. User should always caution of timestamp before the signing a certificate. It can refer to the signing time. Furthermore, If there is backend service in your application, the backend needs to check the timestamp and make sure its compliance with application/business rules.
string: The hostname of the application, it is a similar concept of
Party Ain a contract. For the security purpose, Backend service should always ensure the
domainand hostname of the application are the same. It can prevent cross-domain replay attack.
string: User account which signed the certificate in the hexadecimal string, starts with '0x'.
string: Signature in hexadecimal string, starts with '0x'.
The concept of this proposal does not involve interaction with the blockchain（off-chain）. We don't need to consider the size or storage of the message which application request user to sign. Therefore, we choose a simple, flexible and universal JSON as the encoding format. We define the following rules to make the result deterministic :
- Key of JSON sorted by alphabet ascending;
- Encoding should be compact: no indent, no wrap;
UTF-8as character encoding;
- Format of signer and signature should be a hexadecimal string and starts with
Hashing algorithm should use
blake2b 256bit which is widely used in VeChain.
Signing algorithm should use
secp256k1. The message for signing is the whole payload without signature*, encoded with the described method.
- Encode the message and calculate the hash;
- Recovery the public key by the message hash and signature, then derive the account address;
- Compare the recovered address and the address in the payload. Note: address is case-insensitive when you are comparing by hexadecimal
The certificate include a valid signature field. To get the certificate ID, you have to encode the output by using the above encoding method and hash the encoded output.