Files
xrpl-dev-portal/content/tutorial-regular-keys.md
Jennifer Hasegawa 2c2450d7de addressed feedback
2018-02-08 18:02:46 -08:00

14 KiB

Working with Regular Keys

The XRP Ledger allows an account to authorize a secondary key pair, called a "regular key," to sign future transactions. If the private key of a regular key is compromised, you can remove or replace it without changing the rest of your account and re-establishing its relationships to other accounts. You can also rotate a regular key proactively. (Neither of those things is possible for the master key pair of an account, which is intrinsically linked to the account's address.)

For more information about master and regular keys, see Understanding Master and Regular Keys.

This article provides the following tutorials:

Assigning a Regular Key

This tutorial walks you through the steps required to assign a regular key to your account:

  1. Generate a key
  2. Assign the key to your account as a regular key
  3. Submit an AccountSet transaction using the regular key
  4. Explore next steps

1. Generate a Key

Use the wallet_propose method to generate the key that you'll assign to your account as a regular key.

Here's an example wallet_propose request and response:

WebSocket Request

{
  "method": "wallet_propose"
}

WebSocket Response

{
  "result": {
    "account_id": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
    "key_type": "secp256k1",
    "master_key": "KNEW BENT LYNN LED GAD BEN KENT SHAM HOBO RINK WALT ALLY",
    "master_seed": "sh8i92YRnEjJy3fpFkL8txQSCVo79",
    "master_seed_hex": "966C0F68643EFBA50D58D191D4CA8AA7",
    "public_key": "aBRNH5wUurfhZcoyR6nRwDSa95gMBkovBJ8V4cp1C1pM28H7EPL1",
    "public_key_hex": "03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E"
  },
  "status": "success",
  "type": "response"
}

In the next step, you'll use the account_id from this response to assign the key as a regular key to your account.

2. Assign the Key to Your Account as a Regular Key

Use the SetRegularKey method to assign the key you generated in step 1 to your account as a regular key.

When assigning a regular key to your account for the first time, the SetRegularKey method requires signing by your account's master private key (secret). Transmitting your master private key is dangerous, so we'll complete this transaction in two steps to keep transaction signing separate from transaction submission to the network.

When you make subsequent SetRegularKey requests, you can sign using the existing regular key to replace or remove itself.

Sign Your Transaction

The most secure way to sign a transaction is to do it offline with a signing library, such as RippleAPI. Alternatively, you can sign the transaction using the sign command, but this must be done through a trusted and encrypted connection, or through a local connection, and only to a server you control.

In the transaction JSON, use your account's account_ID as the Account value, your account's master_key, master_seed, or master_seed_hex (master private key) as the secret value, and the account_id generated in step 1 as the RegularKey value.

Here's an example sign request and response for a SetRegularKey type transaction:

WebSocket Request:
{
  "command": "sign",
  "tx_json" : {
      "TransactionType" : "SetRegularKey",
      "Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
      "RegularKey" : "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7"
      },
   "secret" : "ssCATR7CBvn4GLd1UuU2bqqQffHki"
}
WebSocket Response:
{
  "result": {
    "tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
    "tx_json": {
      "Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
      "Fee": "10",
      "Flags": 2147483648,
      "RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
      "Sequence": 4,
      "SigningPubKey": "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
      "TransactionType": "SetRegularKey",
      "TxnSignature": "304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
      "hash": "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
    }
  },
  "status": "success",
  "type": "response"
}

The sign command response contains a tx_blob value, as shown above. The offline signing response contains a signedTransaction value. Both are signed binary representations (blobs) of the transaction.

Next, use the submit command to transmit the transaction blob (tx_blob or signedTransaction) to the network.

Submit Your Transaction

Take the signedTransaction value from the offline signing response or the tx_blob value from the sign command response and submit it as the tx_blob value using the submit command.

Here's an example submit request and response for a SetRegularKey type transaction.

WebSocket Request:
{
    "command": "submit",
    "tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540"
}
WebSocket Response:
{
  "result": {
    "engine_result": "tesSUCCESS",
    "engine_result_code": 0,
    "engine_result_message": "The transaction was applied. Only final in a validated ledger.",
    "tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
    "tx_json": {
      "Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
      "Fee": "10",
      "Flags": 2147483648,
      "RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
      "Sequence": 4,
      "SigningPubKey": "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
      "TransactionType": "SetRegularKey",
      "TxnSignature": "304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
      "hash": "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
    }
  },
  "status": "success",
  "type": "response"
}

Note that the response contains a hash of the transaction, which you can use to look up the transaction's final outcome.

3. Submit an AccountSet Transaction Using the Regular Key

To verify that your account has the regular key set correctly, send an AccountSet transaction from your account, signing it with the regular key you assigned to your account in step 2.

In the request, send your account's account_id as the Account value and the master_key, master_seed, or master_seed_hex (regular private key) generated in step 1 as the secret value.

Here's an example AccountSet request and response. Note that the request does not include any AccountSet options. This means that a successful transaction has no effect other than to confirm that the regular key is set correctly for your account (and to destroy the transaction cost).

WebSocket Request:

{
  "command": "submit",
  "tx_json" : {
    "TransactionType": "AccountSet",
    "Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"
},
   "secret" : "sh8i92YRnEjJy3fpFkL8txQSCVo79"
}

WebSocket Response:

{
  "result": {
    "engine_result": "tesSUCCESS",
    "engine_result_code": 0,
    "engine_result_message": "The transaction was applied. Only final in a validated ledger.",
    "tx_blob": "1200032280000000240000000368400000000000000A732103AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E744730450221008F44064A901C3A170A046673EFC8091F2C409E1DB7D78A5EF0D18E9D868AE21002207F594F3BF3821E6DF64CD283F590F6578F809DFD1CAAF654F187645A7CAB91C48114830923439D307E642CED308FD91EF701A7BAA747",
    "tx_json": {
      "Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
      "Fee": "10",
      "Flags": 2147483648,
      "Sequence": 3,
      "SigningPubKey": "03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E",
      "TransactionType": "AccountSet",
      "TxnSignature": "30450221008F44064A901C3A170A046673EFC8091F2C409E1DB7D78A5EF0D18E9D868AE21002207F594F3BF3821E6DF64CD283F590F6578F809DFD1CAAF654F187645A7CAB91C4",
      "hash": "BED704F2A6A80DA4060446C95802F205EE41977A2F63F10B1F8952FC6D01B35B"
    }
  },
  "status": "success",
  "type": "response"
}

4. Explore Next Steps

Now that you're familiar with the benefits of assigning a regular key to an account, consider taking a look at these related topics and tutorials:

Removing or Changing a Regular Key

If your account's regular key is compromised, or if you just want to periodically change the regular key as a security measure, use the SetRegularKey method to remove or change the regular key for your account.

The steps to change your existing regular key are almost the same as the steps to assign a regular key for the first time. You generate the key and assign it to your account as a regular key, overwriting the existing regular key. However, the main difference is that when changing the existing regular key, you can use the existing regular key to replace itself, whereas when assigning a regular key to an account for the first time, you have to use the account's master key to do it.

For more information about master and regular keys, see Understanding Master and Regular Keys.

If you want to simply remove a compromised regular key from your account, you don't need to generate a key pair first and just use the SetRegularKey method, omitting the RegularKey value in the request. Note that the method fails if you don't have another way of signing for your account currently enabled (either the master key or a signer list).

Here's an example SetRegularKey request and response that removes an existing regular key from an account:

WebSocket Request:

{
   "command" : "submit",
   "tx_json" : {
      "TransactionType" : "SetRegularKey",
      "Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"
   },
   "secret" : "sh8i92YRnEjJy3fpFkL8txQSCVo79"
}

WebSocket Response:

{
  "result": {
    "engine_result": "tesSUCCESS",
    "engine_result_code": 0,
    "engine_result_message": "The transaction was applied. Only final in a validated ledger.",
    "tx_blob": "1200052280000000240000000668400000000000000A732103AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E744630440220703F4EB4D1DF90632DDEB0F3B72B41B7E85C739933C9AF55472BB154637645B202202689C22A10965DA0F0EA1D745EBB8E94E242572490FED69A059D724172E9DCFC8114830923439D307E642CED308FD91EF701A7BAA747",
    "tx_json": {
      "Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
      "Fee": "10",
      "Flags": 2147483648,
      "Sequence": 6,
      "SigningPubKey": "03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E",
      "TransactionType": "SetRegularKey",
      "TxnSignature": "30440220703F4EB4D1DF90632DDEB0F3B72B41B7E85C739933C9AF55472BB154637645B202202689C22A10965DA0F0EA1D745EBB8E94E242572490FED69A059D724172E9DCFC",
      "hash": "15234F29930BFB8A87EB604D4E657CDEE277BAF9D670A90CDE2453A608A9A81C"
    }
  },
  "status": "success",
  "type": "response"
}

The way to verify that regular key removal succeeded is to confirm that you can't send a transaction using the removed regular key.

Here's an example error response for an AccountSet transaction signed using the regular key removed by the SetRegularKey transaction above.

WebSocket Response:

{
  "error": "badSecret",
  "error_code": 41,
  "error_message": "Secret does not match account.",
  "request": {
    "command": "submit",
    "secret": "sh8i92YRnEjJy3fpFkL8txQSCVo79",
    "tx_json": {
      "Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
      "TransactionType": "AccountSet"
    }
  },
  "status": "error",
  "type": "response"
}

In some cases, you can even use the SetRegularKey method to send a key reset transaction without paying the transaction cost. With the enablement of the FeeEscalation amendment, rippled prioritizes key reset transactions above other transactions even though the nominal transaction cost of a key reset transaction is zero.