Concept introduction
DSA is a public key algorithm. It can not be used as encryption, but only as digital signature. reference resources
ECDSA elliptic curve digital signature algorithm (ECDSA) uses Elliptic Curve Cryptography (ECC) to encrypt the digital signature algorithm (DSA). Generated R, s signature value reference
1、 Decode Wallet
That is, read the keystore information from the wallet according to the user password. This is basically the reverse process of wallet generation.
1. Regenerate the derivedkey according to scrypt algorithm As shown in the following figure, check with the create () box
2. Call the performcipheroperation() decryption method according to the derivedkey to get the private key. As shown in the blue box below, it is cross referenced with create()
3. Pass the private key to eckeypair:: create() to get the public key again. Specifically, call sign:: publickeyfromprivate(): BigInteger. Those interested can go in and have a look.
4. Generate credentials class according to eckeypair, which mainly includes eckeypair and wallet address.
It should be noted that the wallet address is re generated according to the public key, not read from the file.
Let's think about the benefits of doing this? (it's safe, isn't it p? What if it's tampered with in the file.)
decrypt. jpg
Specific code
//Wallet. Java internal decoding Wallet
public static ECKeyPair decrypt(String password, WalletFile walletFile)throws CipherException {
validate(walletFile);
WalletFile. Crypto crypto = walletFile. getCrypto();
byte[] mac = Numeric. hexStringToByteArray(crypto.getMac());
byte[] iv = Numeric. hexStringToByteArray(crypto.getCipherparams(). getIv());
byte[] cipherText = Numeric. hexStringToByteArray(crypto.getCiphertext());
byte[] derivedKey;
//Obtain the relevant parameters of scrypt encryption and decode the user password.
WalletFile. KdfParams kdfParams = crypto. getKdfparams();
if (kdfParams instanceof WalletFile.ScryptKdfParams) {
WalletFile. ScryptKdfParams scryptKdfParams =
(WalletFile.ScryptKdfParams) crypto. getKdfparams();
int dklen = scryptKdfParams. getDklen();
int n = scryptKdfParams. getN();
int p = scryptKdfParams. getP();
int r = scryptKdfParams. getR();
byte[] salt = Numeric. hexStringToByteArray(scryptKdfParams.getSalt());
derivedKey = generateDerivedScryptKey(
password. getBytes(Charset.forName("UTF-8")), salt, n, r, p, dklen);
} else if (kdfParams instanceof WalletFile.Aes128CtrKdfParams) {
WalletFile. Aes128CtrKdfParams aes128CtrKdfParams =
(WalletFile.Aes128CtrKdfParams) crypto. getKdfparams();
int c = aes128CtrKdfParams. getC();
String prf = aes128CtrKdfParams. getPrf();
byte[] salt = Numeric. hexStringToByteArray(aes128CtrKdfParams.getSalt());
derivedKey = generateAes128CtrDerivedKey(
password. getBytes(Charset.forName("UTF-8")), salt, c, prf);
} else {
throw new CipherException("Unable to deserialize params: " + crypto.getKdf());
}
byte[] derivedMac = generateMac(derivedKey, cipherText);
if (!Arrays.equals(derivedMac, mac)) {
throw new CipherException("Invalid password provided");
}
byte[] encryptKey = Arrays. copyOfRange(derivedKey, 0, 16);
//Decode ciphertext according to the encryptkey generated by the user password to obtain the private key
byte[] privateKey = performCipherOperation(Cipher.DECRYPT_MODE, iv, encryptKey, cipherText);
return ECKeyPair. create(privateKey);
}
//Credentials. Java, retrieve the address according to the eckeypair parameter and save it into the current class.
public static Credentials create(ECKeyPair ecKeyPair) {
String address = Numeric. prependHexPrefix(Keys.getAddress(ecKeyPair));
return new Credentials(ecKeyPair, address);
}
After the above steps, we decode the wallet, and then we can perform the transfer function according to these information.
2、 Get nonce
Nonce: integer type, which will accumulate with the transactions under the account. The function is to "prevent replay attacks of transactions".
We can query the nonce value of the last transaction by calling the relevant interface of ethscan, which starts from 0.
3、 Code processing
Before starting, introduce the concepts of R, s and V, where R and s are ECDSA signature values. V is chained
1. Initialize rawtransaction class according to nonce, gasprice, gaslimit, etc
That is, the transaction description file.
RawTransaction. createTransaction()
2. Generate byte file according to the description file. TransactionEncoder. signMessage()
This file is a file transferred over the network. This step will perform digital signature and encryption according to ECDSA.
3. Call API? action=eth_ Sendrawtransaction sends the description file to the relevant server.
4. The server broadcasts this file to the ETH public chain.
Author: attacking Xiaoqiang
Link: https://www.jianshu.com/p/5baf171ab4a4
Source: Jianshu
The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.