Ashley is a blockchain security researcher with passion for exploring new challenges and staying up-to-date with the latest technological advancements. In addition, she is also a Solidity and Move developer with experience in building DeFi protocols and conducting vulnerability mining.
Twitter. https://twitter.com/ashleyhsu_eth
In this article, we will delve into the concept of Aptos key rotation and its importance. Before we begin, let's understand what an Aptos account is and what public and private keys do. Aptos accounts support key rotation, which allows you to change your private key without having to create a new account, thus preserving the assets and identity of your original account. In the following section, we will introduce how to use Aptos cli and Python SDK to accomplish key rotation so that you can keep your account assets and identity secure at all times.
0x01 What is an account?
Each Aptos account represents an entity on the blockchain that can send transactions and is identified by a specific 32-byte account address. This account is a container for Move modules and Move resources, and can contain blockchain assets such as coins and NFTs. These assets are represented as resources in the blockchain account, and the account can also perform various operations, such as sending resources to other people. Just as in the Web2 world, your email address represents your email account, in the Aptos blockchain, the account address represents the account itself, which you can use to send and receive assets and so on.
1.1 Public key, private key
Private keys are used in the Aptos blockchain, as in other blockchains, to sign transactions so that they can be recognized and verified, just like in real life when you need to sign a signature or enter a password in order to transfer funds. Signed transactions are the only way to make changes to your account assets, but only the person with the private key can sign the transaction, so the private key is a very important and sensitive set of data.
On other blockchains, your public identity is the public key to your private key, the address can be derived from the public key, and the public key is used to verify signatures. However, Aptos supports key rotation, which causes the public key to change, so addresses are used to represent accounts. Traditionally, each account has a specific address as its identifier, and this address does not change. In Aptos, even if you change the authentication key (which contains the public key), the account address remains unique and does not change.
1.2 Identity authentication key (authentication key)
Aptos Blockchain supports both single-signature and multi-signature accounts. Multi-signature accounts allow multiple users to work together to execute digital signatures to manage account assets. For example, imagine a safe with two locks and two keys, one key held by Alice and the other by Bob. The only way to open this safe would be for both people to provide the keys to unlock it, but not when only one of the keys is present. A multi-signature account is similar in that it is a single account representing multiple parties, and all transactions that occur require the signatures of all parties involved, and can be set at a threshold, for example, 2-of-3 means that two out of three signatures are required to complete the transaction.
Multi-signature accounts use multiple (private and public) key pairs and no single public key will represent this account. Therefore, we need a key that represents this account in order to encapsulate the public keys of all subscribers in the multi-signature account, and this key that represents this account is also known as the authentication key.
Authentication keys are a way to represent all subscribers in a multi-signature account. In short, the authentication key is created by concatenating a serial hash of the public keys of all participating subscribers.
auth_key = sha3-256(pubkey_1 | . . . | pubkey_n | K | 0x01)
included among theseK
is the signature threshold required for validation transactions.0x01
is a 1-byte multi-signature scheme identifier.
For single-signature accounts, authentication keys also exist. The authentication key for a single-signature account only encapsulates a public key to represent the account, and this is done to maintain consistency across all types of accounts.
auth_key = sha3-256(pubkey_A | 0x00)
included among these 0x00
is a 1-byte single-signature scheme identifier.
We can say that an identity authentication key is a broad public representation of a private key.
1.3 Account Address
During the account creation process, after generating a set of public and private keys, a 32-byte authentication key will be calculated and this authentication key will be used as the account address.
Single Signature Accounts:
auth_key = sha3-256(pubkey_A | 0x00)
included among these 0x00
is a 1-byte single-signature scheme identifier.
Multi-signature accounts:
auth_key = sha3-256(pubkey_1 | . . . | pubkey_n | K | 0x01)
included among theseK
is the signature threshold required for validation transactions.0x01
is a 1-byte multi-signature scheme identifier.
However, after key rotation, the identity verification key will change and when a new public-private key pair is generated, the public key will rotate the private key.However, the account address will not change.The 32-byte authentication key is therefore only initially the same as the 32-byte account address. As a result, only initially will the 32-byte authentication key be the same as the 32-byte account address. This decoupling of account and key allows Aptos to seamlessly add new digital signature algorithms to support both public and private key types.
After the account is created, although the private key, public key, and authentication key may change, the account address will beRemain unchanged.The
0x02 Why do we need key rotation?
When private keys are compromised, your account can be attacked. In web2, most people change their passwords regularly to minimize the risk of theft, and in the case of a stolen Instagram or Facebook account, there are other ways to verify your identity, change your password, and get your account back. However, in most blockchains, it's not that simple. Private keys appear in pairs, and the only solution to chaining identities bound to private keys is to create a new account, use the new public and private key pairs, and transfer all assets to that account.
However, this method causes many problems, such as loss of original account assets, OG identity symbols, and remembrance of activities participated in, etc. Therefore, key rotation technology was developed. As a result, key rotation has been developed, and Aptos accounts support key rotation, which allows you to change your private key without having to create a new account, thus preserving the assets and identity of your original account. This means you can keep your original address and others can still send you assets using your original address. The only thing that will change is the authentication key as it is calculated from the public key.
Key rotation technology realizesChained IdentityandsafetySeparation allows you to replace the private key when it is compromised, thus protecting assets from loss or theft. In addition, key rotation also allows us to change the key periodically, minimizing the risk of the private key being stolen and providing more flexibility in using multi-signature accounts.
0x03 Authentication key rotation
Key rotation, in Aptos, is more accurately called authentication key rotation.
The account.move module contains all functions related to Aptos accounts. Users can move their accounts via the account::rotate_authentication_key
Functions to achieve key rotation.
public entry fun rotate_authentication_key(
from_public_key_bytes: vector,
to_scheme: u8, to_public_key_bytes: vector, rotate_authentication_key(
to_public_key_bytes: vector,
cap_rotate_key: vector,
cap_update_table: vector,
) acquires Account, OriginatingAddress {
...
}
In order to authorize the rotation, we need two signatures:
cap_rotate_key
means the current owner of the account has no control over theRotationProofChallenge
The signature of the subscriber certifies that the subscriber intends and has the ability to rotate the authentication key for this account.cap_update_table
The new key to be rotated to (the key that the account owner wants to rotate to) is a pair of keys to be rotated to the new key.RotationProofChallenge
The signature of the subscriber proves that the subscriber owns the new private key and has the right to update it.OriginatingAddress
Mapping and New Address Mapping<new_address, originating_address>
The
In order to validate these two signatures, we need their corresponding public keys and public key schemes: we use the from_scheme
respond in singingfrom_public_key_bytes
Verificationcap_rotate_key
Useto_scheme
respond in singingto_public_key_bytes
Verificationcap_update_table
The
Single SignatureED25519_SCHEME
If you have more than one signature, it will beMULTI_ED25519_SCHEME
The
3.1 Using Aptos cli to achieve single-signature account key rotation
Initially, you can see that the account address and authentication key are the same.
Generate a key:
aptos key generate --key-type ed25519 --output-file output.key
{
"Result": {
"PrivateKey Path": "output.key", "PublicKey Path": "output.key.pub", "output.key.key.pub
"PublicKey Path": "output.key.pub"
}
}
To do key rotation with aptos cli, the parameters can be filled directly into the private key or key file.
aptos account rotate-key --new-private-key-file output.key
aptos account rotate-key --new-private-key 0xae249782eedbfafcc7da157542d1f97d97385cbda36338c806475a3ce127fd90
Do you want to submit a transaction for a range of [52100 - 78100] Octas at a gas unit price of 100 Octas? [yes/no] >
[yes/no] > yes
[yes/no] > yes
"transaction_hash": "0x75c412d82e038f87cec14c6c8b08c7fb08290118437e18433700c0e5d0262854", "gas_used": 52100: 52100
"gas_used": 521, "gas_unit_price": 521, "gas_unit_price".
"gas_unit_price": 100,
"sender": "148f1f6f88d690a04451fa8a548f21129b537cf511cedaa66a6ad93abc83a607",
"sequence_number": 0,
"success": true,
"timestamp_us": 1688636116823320, "version": 571106868
"version": 571106848, "vm_status": 571106848, "vm_status": 571106848
"vm_status": "Executed successfully"
}
Do you want to create a profile for the new key? [yes/no] >
Do you want to create a profile for the new key?
Enter the name for the profile
Enter the name for the profile
Profile Update is saved.
[yes/no] > yes Enter the name for the profile Update Profile Update is saved.
"Result": {
"message": "Profile Update is saved.", "transaction": { "message": "Profile Update is saved.
"transaction": {
"transaction_hash": "0x75c412d82e038f87cec14c6c8cb08c7fb08290118437e18433700c0e5d0262854",
"gas_used": 521, "gas_unit_price": 521, "gas_unit_price".
"gas_unit_price": 100,
"sender": "148f1f6f88d690a04451fa8a548f21129b537cf511cedaa66a6ad93abc83a607",
"sequence_number": 0,
"success": true,
"timestamp_us": 1688636116823320, "version": 571106868
"version": 571106848, "vm_status": 571106848, "vm_status": 571106848
"vm_status": "Executed successfully"
}
}
}
Returning to Aptos explorer, the authentication key has changed and the account address remains the same.
The aptos cli can also be used to look up the account address by using the public key:
aptos account lookup-address --public-key-file output.key.pub
{
"Result": "148f1f6f88d690a04451fa8a548f21129b537cf511cedaa66a6ad93abc83a607"
}
3.2 Rotating a single-signature account to a multi-signature account with Python SDK
The multisig example of python sdk in aptos-core is for reference, you can modify it according to your own usage situation.
Summarize the process:
- Create a Single Signature Account
- Create a multi-signature account, this is to create a 2-of-3 multi-signature account.
- Sign rotation proof challenge
- Perform a rotation of the authentication key
3.3 Environmental Installation
Install Poetry
It is recommended to use Poetry for Python suite management.
Install Poetry
curl -sSL https://install.python-poetry.org | python3 -
Add Poetry to the PATH according to your system environment. .zshrc
maybe .bashrc
export PATH="$HOME/.local/bin:$PATH"
Confirm Poetry installation is complete
poetry --version
Installing the Aptos Python SDK
pip3 install aptos-sdk
For more information, please refer to the official website.
3.4 Execute Aptos SDK Example
git clone https://github.com/aptos-labs/aptos-core.git
cd aptos-core/ecosystem/python/sdk
Recreating the Project's Poetry Virtual Environment
poetry env use python3
Installation Kit
poetry install
Execution
poetry run python -m examples.multisig
3.5 Settings
Introduce the library to be used:
from aptos_sdk.account import Account, RotationProofChallenge
from aptos_sdk.account_address import AccountAddress
from aptos_sdk.authenticator import Authenticator, MultiEd25519Authenticator
from aptos_sdk.bcs import Serializer
from aptos_sdk.client import FaucetClient, RestClient
from aptos_sdk.ed25519 import MultiPublicKey, MultiSignature
from aptos_sdk.transactions import (
EntryFunction, RawTransaction, RawTransaction, RawTransaction
EntryFunction, RawTransaction, RawTransaction, RawTransaction
EntryFunction, RawTransaction, Script, ScriptArgument
Script, ScriptArgument, SignedTransaction, SignedTransaction
SignedTransaction, SignedTransaction
TransactionArgument.
TransactionPayload.
)
from aptos_sdk.type_tag import StructTag, TypeTag
Configure the connection node and tap information, which uses the devnet environment:
NODE_URL = os.getenv("APTOS_NODE_URL", "https://fullnode.devnet.aptoslabs.com/v1")
FAUCET_URL = os.getenv(
"APTOS_FAUCET_URL",
"https://faucet.devnet.aptoslabs.com".
)
Initialize Client
rest_client = RestClient(NODE_URL)
faucet_client = FaucetClient(FAUCET_URL, rest_client)
3.6 Creating a Visa Account
deedee = Account.generate()
faucet_client.fund_account(deedee.address(), 50_000_000)
deedee_balance = rest_client.account_balance(deedee.address())
Deedee's address: 0x7ee730f9bb87e78b0f51b4399113af2ed6bc50d0a8e0bc27f914c287af6a9d49
Deedee's auth key: 0x7ee730f9bb87e78b0f51b4399113af2ed6bc50d0a8e0bc27f914c287af6a9d49
Deedee's public key: 0x641cb41098c6cea2c2643508ee28e116459c666e353d6dc708290c5dd8f27169
Deedee's balance: 50000000
3.7 Creating Multi-Signature Accounts
Here we choose to create 2-of-3 multi-signature accounts, so we create three single-signature accounts first, which will have three public-private key pairs.
# generate account
alice = Account.generate()
bob = Account.generate()
chad = Account.generate()
# fund account
faucet_client.fund_account(alice.address(), 10_000_000)
faucet_client.fund_account(bob.address(), 20_000_000)
faucet_client.fund_account(chad.address(), 30_000_000)
=== Account addresses ===
Alice: 0xe2f0ac3bf3066f83c3f13df40eb1f1e980b15bbf6198dfee0d4bfd741baf92a8
Bob: 0x55234e90dec96a74938a4da2f7815b97494fc3c4b4d8782fa9c0e83399613310
Chad: 0x9b2ff4d016b1dead4c79487275bcb332ce56d0c707bc07cf0f15e223e64122a0
=== Authentication keys ===
Alice: 0xe2f0ac3bf3066f83c3f13df40eb1f1e980b15bbf6198dfee0d4bfd741baf92a8
Bob: 0x55234e90dec96a74938a4da2f7815b97494fc3c4b4d8782fa9c0e83399613310
Chad: 0x9b2ff4d016b1dead4c79487275bcb332ce56d0c707bc07cf0f15e223e64122a0
=== Public keys ===
Alice: 0x53a03cc129319935ddabc8ac2afb0c5e320cd5bda347413fb6fe33bcdd0b7fb3
Bob: 0x51a95405c021b0449d11d71797ecb72e931c045a55f69ae96aa6c87d55ba8098
Chad: 0x74ac180a4c5b4f6e14f13b8a5e6dd19d102c0e3543268816dcb6484f0da5444d
Next, use the public key generated in the previous step to generate a 2-of-3 multi-signature account public key and address.
# generate public key from Alice, Bob and Chad's public key
threshold = 2
multisig_public_key = MultiPublicKey(
[alice.public_key(), bob.public_key(), chad.public_key()], threshold
)
# get address
multisig_address = AccountAddress.from_multi_ed25519(multisig_public_key)
# fund account
faucet_client.fund_account(multisig_address, 40_000_000)
=== 2-of-3 Multisig account ===
Account public key: 2-of-3 Multi-Ed25519 public key
Account address: 0x77e7728ef2189e48b3b898087c460a63f14955bcc6e4915b95aab8f864be8d05
3.8 Signature rotation proof challenge
In the case of call-ups rotate_authentication_key
Before that, you need to prepare the incoming parameters, which are cap_rotate_key
up to cap_update_table
Thecap_rotate_key
Table Deedee approves this identity verification key rotation.cap_update_table
Verify that authentication key rotation is approved for multi-signature accounts.
rotation_proof_challenge = RotationProofChallenge(
sequence_number=0,
originator=deedee.address(),
current_auth_key=deedee.address(),
new_public_key=multisig_public_key.to_bytes(), )
)
serializer = Serializer()
rotation_proof_challenge.serialize(serializer)
rotation_proof_challenge_bcs = serializer.output()
cap_rotate_key = deedee.sign(rotation_proof_challenge_bcs).data()
cap_update_table = MultiSignature(
multisig_public_key,
[
(bob.public_key(), bob.sign(rotation_proof_challenge_bcs)), [
(chad.public_key(), chad.sign(rotation_proof_challenge_bcs)), [
]
).to_bytes()
=== Signing rotation proof challenge ===
cap_rotate_key. 0x497d25f09c29df422e620dd8eaf44ee9b7bbc2844b5143ade652d9a0d084cd1b59e66e6d0c8ebd3a4e6d5b70ddc0f635bbe321ea6ac2902d2ab07e3248e5ac08
cap_update_table. 0xe40f69589e89beca67362c2cadb145df92d77351bfe77aa9318af88f1453576b2fc8e8723fca961e696014a0077946a762c18d7a64547b3ec1f0539f88889303d89de34be00ada58151a124cc3610226ca1c0ca9814be9040bba3c6d02f169a53b922ce6cb026165746c8e90837affac8692206dc9eb0f82f0117742d331670a60000000
3.9 Perform authentication key rotation
It is now possible to submit transactions for authentication key rotation. Upon execution, the rotated authentication key matches the address of the multi-signature account.
from_scheme = Authenticator.ED25519
from_public_key_bytes = deedee.public_key().key.encode()
to_scheme = Authenticator.MULTI_ED25519
to_public_key_bytes = multisig_public_key.to_bytes()
entry_function = EntryFunction.natural(
module="0x1::account",
function="rotate_authentication_key",
ty_args=[],
args=[
TransactionArgument(from_scheme, Serializer.u8),
TransactionArgument(from_public_key_bytes, Serializer.to_bytes),
TransactionArgument(to_scheme, Serializer.u8),
TransactionArgument(to_public_key_bytes, Serializer.to_bytes),
TransactionArgument(cap_rotate_key, Serializer.to_bytes),
TransactionArgument(cap_update_table, Serializer.to_bytes),
]
)
signed_transaction = rest_client.create_bcs_signed_transaction(
deedee, TransactionPayload(entry_function)
)
# auth key before key rotation
auth_key = rest_client.account(deedee.address())["authentication_key"]
print(f "Auth key pre-rotation: {auth_key}")
# send key rotation tx
tx_hash = rest_client.submit_bcs_transaction(signed_transaction)
rest_client.wait_for_transaction(tx_hash)
print(f "Transaction hash: {tx_hash}")
# auth key after key rotation
auth_key = rest_client.account(deedee.address())["authentication_key"]
print(f "New auth key: {auth_key}")
print(f "1st multisig address: {multisig_address}")
=== Submitting authentication key rotation transaction ===
Auth key pre-rotation: 0x7ee730f9bb87e78b0f51b4399113af2ed6bc50d0a8e0bc27f914c287af6a9d49
Transaction hash: 0x16046f72559268dc4025d28bbc2d8c91ab7a780e237cbf430965477910014df0
New auth key: 0x77e7728ef2189e48b3b898087c460a63f14955bcc6e4915b95aab8f864be8d05
1st multisig address: 0x77e7728ef2189e48b3b898087c460a63f14955bcc6e4915b95aab8f864be8d05
0x04 Summary
Aptos accounts decouple chained address identities from private keys, offering single-signature and multi-signature accounts, and most importantly, key rotation. Addresses remain the same after account creation, even after key rotation. Key rotation changes the public and private key pairs as well as the authentication key.
0x05 Reference
- https://aptos.dev/concepts/accounts/
- https://medium.com/@martian-wallet/accounts-in-aptos-1ecc3f0b1213
- https://forum.aptoslabs.com/t/aptos-review-account-system/150437
- https://aptos.dev/tutorials/your-first-multisig/
All of the above content is reproduced from the Internet, does not represent the position of AptosNews, is not investment advice, investment risk, the market need to be cautious, such as infringement, please contact the administrator to delete.