Signing and Verifying Arbitrary Data
Signing and Verifying Arbitrary Data
Cryptographic signatures are a key part of the blockchain. They prove ownership of an address without exposing its private key. While primarily used to sign transactions, you can also use cryptographic signatures to sign arbitrary messages.
FCL has a feature that lets you send arbitrary data to a configured wallet or service. The user may approve signing it with their private keys.
Verify user signatures
What makes message signatures more interesting is that we can use Flow blockchain to verify the signatures. Cadence has a built-in function publicKey.verify that will verify a signature against a Flow account given the account address.
FCL includes a utility function, AppUtils.verifyUserSignatures, that verifies one or more signatures against an account's public key on the Flow blockchain.
You can use both in tandem to prove a user is in control of a private key or keys.
This allows cryptographically-secure login flow with a message-signing-based authentication mechanism with a user’s public address as their identifier.
currentUser.signUserMessage()
A method that allows the user to personally sign data via FCL Compatible Wallets or Services.
Requires authentication/configuration with an authorized signing service.
Arguments
| Name | Type | Description |
|---|---|---|
message | string | A hexadecimal string to be signed |
Returns
| Type | Description |
|---|---|
Array | An Array of CompositeSignatures: signature |
Usage
_10import * as fcl from "@onflow/fcl"_10_10const signMessage = async () => {_10 const MSG = Buffer.from("FOO").toString("hex")_10 try {_10 return await fcl.currentUser.signUserMessage(MSG)_10 } catch (error) {_10 console.log(error)_10 }_10}
AppUtils.verifyUserSignatures
⚠️ fcl.config.flow.network or options override is required to use this API. See FCL Configuration.
A method to verify that a user's private keys signed a message, which allows applications to cryptographically verify Flow account ownership. This is typically used with the response from currentUser.signUserMessage.
Arguments
| Name | Type | Description |
|---|---|---|
message | string (required) | A hexadecimal string |
compositeSignatures | Array (required) | An Array of CompositeSignatures |
opts | Object (optional) | opts.fclCryptoContract can be provided to override FCLCryptoContract address for local development |
Returns
| Type | Description |
|---|---|
| Boolean | true if verified or false |
Usage
_20/**_20 * Verify a valid signature/s for an account on Flow._20 *_20 * @param {string} msg - A message string in hexadecimal format_20 * @param {Array} compSigs - An array of Composite Signatures_20 * @param {string} compSigs[].addr - The account address_20 * @param {number} compSigs[].keyId - The account keyId_20 * @param {string} compSigs[].signature - The signature to verify_20 * @param {Object} [opts={}] - Options object_20 * @param {string} opts.fclCryptoContract - An optional override of Flow account address where the FCLCrypto contract is deployed_20 * @return {bool}_20 *_20 * @example_20 *_20 * const isValid = await fcl.AppUtils.verifyUserSignatures(_20 * Buffer.from('FOO').toString("hex"),_20 * [{f_type: "CompositeSignature", f_vsn: "1.0.0", addr: "0x123", keyId: 0, signature: "abc123"}],_20 * {fclCryptoContract}_20 * )_20 */
Examples
Use cases include cryptographic login, message validation, verifiable credentials, and others.