NEP2
What is NEP-2?
NEP-2 is a standard used on the Neo blockchain to encrypt and decrypt private keys. Wallet users refer to NEP-2 keys as encrypted keys. Without encryption, private keys are vulnerable to theft or unauthorized access. NEP-2 encryption secures private keys by requiring a passphrase to encrypt and decrypt them.
When a user creates a new wallet on the Neo blockchain, the wallet software generates a private key. The key is then encrypted using a password. The encrypted key is stored in the wallet file. When the user wants to access that account, they must provide the passphrase to decrypt the private key.
The process of encrypting the private key is CPU-intensive, making it more secure against brute-force attacks. Existing Neo wallets such as Neon Wallet and Neo Line support NEP-2 encrypted keys.
NEP-2 - Key Concepts
- Encryption and Decryption: NEP-2 encrypts and decrypts private keys using a passphrase.
- CPU-Intensive Encryption: The encryption process is CPU-intensive, making it more secure against brute-force attacks.
- Used in Neo Wallets: NEP-2 is used in Neo wallets to secure private keys.
- Checksum: NEP-2 includes a checksum to verify the passphrase’s correctness during decryption.
- Used in NEP-6 Wallets: NEP-2 is used in NEP-6 wallets inside the ‘key’ field.
- Prefix and Encoding: Encrypted keys start with the prefix ‘6P’ and are encoded in Base58.
- Address Salting: The address is used to increase the security of the encryption process.
NEP-2 Encryption Process
The process to encrypt a private key using NEP-2 is described in the NEP-2 proposal. Using a Neo account, the process involves the following steps:
- Compute the Address Hash: Use the SHA-256 hash function twice on the account’s address.
- Take the First Four Bytes: Take the first four bytes of the double SHA-256 hash as the checksum.
- Use the Scrypt Key Derivation Function: Use the Scrypt key derivation function to derive a key from the passphrase using the address hash bytes as salt.
- Scrypt Parameters: The Scrypt parameters are set to N=16384, r=8, p=8, and the derived key length is 64 bytes.
- Use Derived Key Halves for Encryption:
- Split the 64-byte derived key into two halves. The first half is used for XOR operations and the second half is used as the AES encryption key.
- AES Encryption:
- Encrypt the First Half of the Private Key: XOR the first 16 bytes of the private key with the first 16 bytes of the first half of the derived key. Use the second half of the derived key as the AES key to encrypt this block.
- Encrypt the Second Half of the Private Key: XOR the second 16 bytes of the private key with the second 16 bytes of the first half of the derived key. Again, use the second half of the derived key as the AES key to encrypt this block.
- Assemble the Encrypted Key: The encrypted private key is assembled as follows:
- Start with the prefix
0x01 0x42
, followed by a flag byte that typically indicates if the key is compressed. - Append the first four bytes of the address hash.
- Concatenate the results of the AES encrypted blocks.
- Start with the prefix
- Base58Check Encoding: Finally, encode the assembled encrypted private key using Base58Check to ensure it includes a checksum for error-checking.
NEP-2 Decryption Process
To decrypt a NEP-2 encrypted private key, follow these steps:
Collect Encrypted Private Key and Passphrase: Retrieve the Base58Check-encoded encrypted private key and the passphrase from the user.
Base58Check Decode: Decode the Base58Check-encoded encrypted private key to access the raw encrypted data.
Extract the Address Hash and Encrypted Blocks: From the decoded data, extract the address hash and the two 16-byte blocks of encrypted key material (
encryptedhalf1
andencryptedhalf2
).Derive Keys Using Scrypt:
- Use the Scrypt key derivation function with the passphrase and the extracted address hash as the salt.
- Set the parameters to N=16384, r=8, p=8, and derive a 64-byte key.
- Split the derived key into
derivedhalf1
(used for final XOR operations) andderivedhalf2
(used as the AES decryption key).
AES Decrypt the Encrypted Blocks:
- Use
AES256Decrypt
onencryptedhalf1
withderivedhalf2
to decrypt the first block. - Repeat the decryption for
encryptedhalf2
.
- Use
Merge and XOR:
- Merge the decrypted outputs of
encryptedhalf1
andencryptedhalf2
. - XOR the merged result with
derivedhalf1
to reconstruct the plaintext private key.
- Merge the decrypted outputs of
Convert Plaintext Private Key to NEO Address: Convert the decrypted plaintext private key back into a NEO address.
Verify Address Hash:
- Recompute the SHA-256 hash of the NEO address from the decrypted private key twice.
- Check if this computed hash matches the
addresshash
from the encrypted key. - If they do not match, the passphrase is incorrect or the key has been tampered with.
This decryption process ensures that the private key is securely recovered only if the correct passphrase is provided, protecting against unauthorized access and data corruption.