diff --git a/core/src/main/java/org/bitcoinj/core/Transaction.java b/core/src/main/java/org/bitcoinj/core/Transaction.java index d1975ed79..73f4cc9b9 100644 --- a/core/src/main/java/org/bitcoinj/core/Transaction.java +++ b/core/src/main/java/org/bitcoinj/core/Transaction.java @@ -25,6 +25,7 @@ import org.bitcoinj.base.Coin; import org.bitcoinj.base.Sha256Hash; import org.bitcoinj.base.VarInt; import org.bitcoinj.base.internal.TimeUtils; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.base.utils.ByteUtils; import org.bitcoinj.core.TransactionConfidence.ConfidenceType; import org.bitcoinj.crypto.ECKey; @@ -40,7 +41,6 @@ import org.bitcoinj.signers.TransactionSigner; import org.bitcoinj.utils.ExchangeRate; import org.bitcoinj.wallet.Wallet; import org.bitcoinj.wallet.WalletTransaction.Pool; -import org.bouncycastle.crypto.params.KeyParameter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -1188,7 +1188,7 @@ public class Transaction extends ChildMessage { * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature(int inputIndex, ECKey key, - @Nullable KeyParameter aesKey, + @Nullable AesKey aesKey, byte[] redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript, hashType, anyoneCanPay); @@ -1209,7 +1209,7 @@ public class Transaction extends ChildMessage { * @return A newly calculated signature object that wraps the r, s and sighash components. */ public TransactionSignature calculateSignature(int inputIndex, ECKey key, - @Nullable KeyParameter aesKey, + @Nullable AesKey aesKey, Script redeemScript, SigHash hashType, boolean anyoneCanPay) { Sha256Hash hash = hashForSignature(inputIndex, redeemScript.getProgram(), hashType, anyoneCanPay); @@ -1372,7 +1372,7 @@ public class Transaction extends ChildMessage { public TransactionSignature calculateWitnessSignature( int inputIndex, ECKey key, - @Nullable KeyParameter aesKey, + @Nullable AesKey aesKey, byte[] scriptCode, Coin value, SigHash hashType, @@ -1384,7 +1384,7 @@ public class Transaction extends ChildMessage { public TransactionSignature calculateWitnessSignature( int inputIndex, ECKey key, - @Nullable KeyParameter aesKey, + @Nullable AesKey aesKey, Script scriptCode, Coin value, SigHash hashType, diff --git a/core/src/main/java/org/bitcoinj/crypto/AesKey.java b/core/src/main/java/org/bitcoinj/crypto/AesKey.java new file mode 100644 index 000000000..cd6868986 --- /dev/null +++ b/core/src/main/java/org/bitcoinj/crypto/AesKey.java @@ -0,0 +1,80 @@ +/* + * Copyright by the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.bitcoinj.crypto; + +import org.bouncycastle.crypto.params.KeyParameter; + +/** + * Wrapper for a {@code byte[]} containing an AES Key. This is a replacement for Bouncy Castle's {@link KeyParameter} which + * was used for this purpose in previous versions of bitcoinj. Unfortunately, this created a Gradle _API_ dependency + * on Bouncy Castle when that wasn't strictly necessary. + *

+ * We have made this change without deprecation because it affected many method signatures and because updating is a trivial change. + * If for some reason you have code that uses the Bouncy Castle {@link KeyParameter} type and need to convert + * to or from {@code AesKey}, you can temporarily use {@link #ofKeyParameter(KeyParameter)} or {@link #toKeyParameter()} + */ +public class AesKey { + private final byte[] bytes; + + /** + * Wrapper for a {@code byte[]} containing an AES Key + * @param keyBytes implementation-dependent AES Key bytes + */ + public AesKey(byte[] keyBytes) { + // Make defensive copy, so AesKey is effectively immutable + this.bytes = new byte[keyBytes.length]; + System.arraycopy(keyBytes, 0, this.bytes, 0, keyBytes.length); + } + + /** + * @return The key bytes + */ + public byte[] bytes() { + return bytes; + } + + /** + * Provided to ease migration from {@link KeyParameter}. + * @return The key bytes + * @deprecated Use {@link #bytes()} + */ + @Deprecated + public byte[] getKey() { + return bytes(); + } + + /** + * Provided to ease migration from {@link KeyParameter}. + * @param keyParameter instance to convert + * @return new, preferred container for AES keys + * @deprecated Use {@code new AesKey(keyParameter.bytes())} + */ + @Deprecated + public static AesKey ofKeyParameter(KeyParameter keyParameter) { + return new AesKey(keyParameter.getKey()); + } + + /** + * Provided to ease migration from {@link KeyParameter}. + * @return if for some reason you still need (temporarily, we hope) a {@link KeyParameter} + * @deprecated Use {@code new KeyParameter(key.bytes)} + */ + @Deprecated + public KeyParameter toKeyParameter() { + return new KeyParameter(this.bytes()); + } +} diff --git a/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java b/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java index 393763dcc..0ea5e9e68 100644 --- a/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java +++ b/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java @@ -26,7 +26,6 @@ import org.bitcoinj.base.Base58; import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.base.Sha256Hash; import org.bitcoinj.crypto.internal.CryptoUtils; -import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.math.ec.ECPoint; import javax.annotation.Nullable; @@ -295,11 +294,11 @@ public class DeterministicKey extends ECKey { } @Override - public DeterministicKey encrypt(KeyCrypter keyCrypter, KeyParameter aesKey) throws KeyCrypterException { + public DeterministicKey encrypt(KeyCrypter keyCrypter, AesKey aesKey) throws KeyCrypterException { throw new UnsupportedOperationException("Must supply a new parent for encryption"); } - public DeterministicKey encrypt(KeyCrypter keyCrypter, KeyParameter aesKey, @Nullable DeterministicKey newParent) throws KeyCrypterException { + public DeterministicKey encrypt(KeyCrypter keyCrypter, AesKey aesKey, @Nullable DeterministicKey newParent) throws KeyCrypterException { // Same as the parent code, except we construct a DeterministicKey instead of an ECKey. checkNotNull(keyCrypter); if (newParent != null) @@ -357,7 +356,7 @@ public class DeterministicKey extends ECKey { } @Override - public ECDSASignature sign(Sha256Hash input, @Nullable KeyParameter aesKey) throws KeyCrypterException { + public ECDSASignature sign(Sha256Hash input, @Nullable AesKey aesKey) throws KeyCrypterException { if (isEncrypted()) { // If the key is encrypted, ECKey.sign will decrypt it first before rerunning sign. Decryption walks the // key hierarchy to find the private key (see below), so, we can just run the inherited method. @@ -374,7 +373,7 @@ public class DeterministicKey extends ECKey { } @Override - public DeterministicKey decrypt(KeyCrypter keyCrypter, KeyParameter aesKey) throws KeyCrypterException { + public DeterministicKey decrypt(KeyCrypter keyCrypter, AesKey aesKey) throws KeyCrypterException { checkNotNull(keyCrypter); // Check that the keyCrypter matches the one used to encrypt the keys, if set. if (this.keyCrypter != null && !this.keyCrypter.equals(keyCrypter)) @@ -389,13 +388,13 @@ public class DeterministicKey extends ECKey { } @Override - public DeterministicKey decrypt(KeyParameter aesKey) throws KeyCrypterException { + public DeterministicKey decrypt(AesKey aesKey) throws KeyCrypterException { return (DeterministicKey) super.decrypt(aesKey); } // For when a key is encrypted, either decrypt our encrypted private key bytes, or work up the tree asking parents // to decrypt and re-derive. - private BigInteger findOrDeriveEncryptedPrivateKey(KeyCrypter keyCrypter, KeyParameter aesKey) { + private BigInteger findOrDeriveEncryptedPrivateKey(KeyCrypter keyCrypter, AesKey aesKey) { if (encryptedPrivateKey != null) { byte[] decryptedKey = keyCrypter.decrypt(encryptedPrivateKey, aesKey); if (decryptedKey.length != 32) @@ -753,7 +752,7 @@ public class DeterministicKey extends ECKey { } @Override - public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable KeyParameter aesKey, StringBuilder builder, + public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable AesKey aesKey, StringBuilder builder, Network network, ScriptType outputScriptType, @Nullable String comment) { builder.append(" addr:").append(toAddress(outputScriptType, network).toString()); builder.append(" hash160:").append(ByteUtils.formatHex(getPubKeyHash())); @@ -767,11 +766,11 @@ public class DeterministicKey extends ECKey { } /** - * @deprecated Use {@link #formatKeyWithAddress(boolean, KeyParameter, StringBuilder, Network, ScriptType, String)} + * @deprecated Use {@link #formatKeyWithAddress(boolean, AesKey, StringBuilder, Network, ScriptType, String)} */ @Override @Deprecated - public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable KeyParameter aesKey, StringBuilder builder, + public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable AesKey aesKey, StringBuilder builder, NetworkParameters params, ScriptType outputScriptType, @Nullable String comment) { formatKeyWithAddress(includePrivateKeys, aesKey, builder, params.network(), outputScriptType, comment); } diff --git a/core/src/main/java/org/bitcoinj/crypto/ECKey.java b/core/src/main/java/org/bitcoinj/crypto/ECKey.java index fb54df7fa..229e062e4 100644 --- a/core/src/main/java/org/bitcoinj/crypto/ECKey.java +++ b/core/src/main/java/org/bitcoinj/crypto/ECKey.java @@ -59,7 +59,6 @@ import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; -import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.signers.ECDSASigner; import org.bouncycastle.crypto.signers.HMacDSAKCalculator; import org.bouncycastle.math.ec.ECAlgorithms; @@ -570,7 +569,7 @@ public class ECKey implements EncryptableItem { * @throws KeyCrypterException if there's something wrong with aesKey. * @throws ECKey.MissingPrivateKeyException if this key cannot sign because it's pubkey only. */ - public ECDSASignature sign(Sha256Hash input, @Nullable KeyParameter aesKey) throws KeyCrypterException { + public ECDSASignature sign(Sha256Hash input, @Nullable AesKey aesKey) throws KeyCrypterException { KeyCrypter crypter = getKeyCrypter(); if (crypter != null) { if (aesKey == null) @@ -804,10 +803,10 @@ public class ECKey implements EncryptableItem { * * @throws IllegalStateException if this ECKey does not have the private part. * @throws KeyCrypterException if this ECKey is encrypted and no AESKey is provided or it does not decrypt the ECKey. - * @deprecated use {@link #signMessage(String, KeyParameter, ScriptType)} instead and specify the correct script type + * @deprecated use {@link #signMessage(String, AesKey, ScriptType)} instead and specify the correct script type */ @Deprecated - public String signMessage(String message, @Nullable KeyParameter aesKey) throws KeyCrypterException { + public String signMessage(String message, @Nullable AesKey aesKey) throws KeyCrypterException { return signMessage(message, aesKey, ScriptType.P2PKH); } @@ -819,7 +818,7 @@ public class ECKey implements EncryptableItem { * @throws IllegalStateException if this ECKey does not have the private part. * @throws KeyCrypterException if this ECKey is encrypted and no AESKey is provided or it does not decrypt the ECKey. */ - public String signMessage(String message, @Nullable KeyParameter aesKey, ScriptType scriptType) throws KeyCrypterException { + public String signMessage(String message, @Nullable AesKey aesKey, ScriptType scriptType) throws KeyCrypterException { if (!isCompressed() && (scriptType == ScriptType.P2WPKH || scriptType == ScriptType.P2SH)) { throw new IllegalArgumentException("Segwit P2WPKH and P2SH-P2WPKH script types only can be used with compressed keys. See BIP 141."); } @@ -1101,7 +1100,7 @@ public class ECKey implements EncryptableItem { * @param aesKey The KeyParameter with the AES encryption key (usually constructed with keyCrypter#deriveKey and cached as it is slow to create). * @return encryptedKey */ - public ECKey encrypt(KeyCrypter keyCrypter, KeyParameter aesKey) throws KeyCrypterException { + public ECKey encrypt(KeyCrypter keyCrypter, AesKey aesKey) throws KeyCrypterException { checkNotNull(keyCrypter); final byte[] privKeyBytes = getPrivKeyBytes(); EncryptedData encryptedPrivateKey = keyCrypter.encrypt(privKeyBytes, aesKey); @@ -1118,7 +1117,7 @@ public class ECKey implements EncryptableItem { * @param keyCrypter The keyCrypter that specifies exactly how the decrypted bytes are created. * @param aesKey The KeyParameter with the AES encryption key (usually constructed with keyCrypter#deriveKey and cached). */ - public ECKey decrypt(KeyCrypter keyCrypter, KeyParameter aesKey) throws KeyCrypterException { + public ECKey decrypt(KeyCrypter keyCrypter, AesKey aesKey) throws KeyCrypterException { checkNotNull(keyCrypter); // Check that the keyCrypter matches the one used to encrypt the keys, if set. if (this.keyCrypter != null && !this.keyCrypter.equals(keyCrypter)) @@ -1142,7 +1141,7 @@ public class ECKey implements EncryptableItem { * * @param aesKey The KeyParameter with the AES encryption key (usually constructed with keyCrypter#deriveKey and cached). */ - public ECKey decrypt(KeyParameter aesKey) throws KeyCrypterException { + public ECKey decrypt(AesKey aesKey) throws KeyCrypterException { final KeyCrypter crypter = getKeyCrypter(); if (crypter == null) throw new KeyCrypterException("No key crypter available"); @@ -1152,7 +1151,7 @@ public class ECKey implements EncryptableItem { /** * Creates decrypted private key if needed. */ - public ECKey maybeDecrypt(@Nullable KeyParameter aesKey) throws KeyCrypterException { + public ECKey maybeDecrypt(@Nullable AesKey aesKey) throws KeyCrypterException { return isEncrypted() && aesKey != null ? decrypt(aesKey) : this; } @@ -1163,11 +1162,11 @@ public class ECKey implements EncryptableItem { * bitcoins controlled by the private key) you can use this method to check when you *encrypt* a wallet that * it can definitely be decrypted successfully.

* - *

See {@link Wallet#encrypt(KeyCrypter keyCrypter, KeyParameter aesKey)} for example usage.

+ *

See {@link Wallet#encrypt(KeyCrypter keyCrypter, AesKey aesKey)} for example usage.

* * @return true if the encrypted key can be decrypted back to the original key successfully. */ - public static boolean encryptionIsReversible(ECKey originalKey, ECKey encryptedKey, KeyCrypter keyCrypter, KeyParameter aesKey) { + public static boolean encryptionIsReversible(ECKey originalKey, ECKey encryptedKey, KeyCrypter keyCrypter, AesKey aesKey) { try { ECKey rebornUnencryptedKey = encryptedKey.decrypt(keyCrypter, aesKey); byte[] originalPrivateKeyBytes = originalKey.getPrivKeyBytes(); @@ -1267,17 +1266,17 @@ public class ECKey implements EncryptableItem { * Produce a string rendering of the ECKey INCLUDING the private key. * Unless you absolutely need the private key it is better for security reasons to just use {@link #toString()}. */ - public String toStringWithPrivate(@Nullable KeyParameter aesKey, Network network) { + public String toStringWithPrivate(@Nullable AesKey aesKey, Network network) { return toString(true, aesKey, network); } /** * Produce a string rendering of the ECKey INCLUDING the private key. * Unless you absolutely need the private key it is better for security reasons to just use {@link #toString()}. - * @deprecated Use {@link #toStringWithPrivate(KeyParameter, Network)} + * @deprecated Use {@link #toStringWithPrivate(AesKey, Network)} */ @Deprecated - public String toStringWithPrivate(@Nullable KeyParameter aesKey, NetworkParameters params) { + public String toStringWithPrivate(@Nullable AesKey aesKey, NetworkParameters params) { return toStringWithPrivate(aesKey, params.network()); } @@ -1302,7 +1301,7 @@ public class ECKey implements EncryptableItem { return getPrivateKeyAsWiF(params.network()); } - private String toString(boolean includePrivate, @Nullable KeyParameter aesKey, Network network) { + private String toString(boolean includePrivate, @Nullable AesKey aesKey, Network network) { final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this).omitNullValues(); helper.add("pub HEX", getPublicKeyAsHex()); if (includePrivate) { @@ -1328,16 +1327,16 @@ public class ECKey implements EncryptableItem { } /** - * @deprecated Use {@link #toString(boolean, KeyParameter, Network)} + * @deprecated Use {@link #toString(boolean, AesKey, Network)} */ @Deprecated - private String toString(boolean includePrivate, @Nullable KeyParameter aesKey, @Nullable NetworkParameters params) { + private String toString(boolean includePrivate, @Nullable AesKey aesKey, @Nullable NetworkParameters params) { Network network = (params != null) ? params.network() : BitcoinNetwork.MAINNET; return toString(includePrivate, aesKey, network); } - public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable KeyParameter aesKey, StringBuilder builder, + public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable AesKey aesKey, StringBuilder builder, Network network, ScriptType outputScriptType, @Nullable String comment) { builder.append(" addr:"); if (outputScriptType != null) { @@ -1365,10 +1364,10 @@ public class ECKey implements EncryptableItem { } /** - * @deprecated Use {@link #formatKeyWithAddress(boolean, KeyParameter, StringBuilder, Network, ScriptType, String)} + * @deprecated Use {@link #formatKeyWithAddress(boolean, AesKey, StringBuilder, Network, ScriptType, String)} */ @Deprecated - public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable KeyParameter aesKey, StringBuilder builder, + public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable AesKey aesKey, StringBuilder builder, NetworkParameters params, ScriptType outputScriptType, @Nullable String comment) { formatKeyWithAddress(includePrivateKeys, aesKey, builder, params.network(), outputScriptType, comment); } diff --git a/core/src/main/java/org/bitcoinj/crypto/KeyCrypter.java b/core/src/main/java/org/bitcoinj/crypto/KeyCrypter.java index b6c8931e1..addc0b5ef 100644 --- a/core/src/main/java/org/bitcoinj/crypto/KeyCrypter.java +++ b/core/src/main/java/org/bitcoinj/crypto/KeyCrypter.java @@ -17,7 +17,6 @@ package org.bitcoinj.crypto; import org.bitcoinj.wallet.Protos.Wallet.EncryptionType; -import org.bouncycastle.crypto.params.KeyParameter; /** *

A KeyCrypter can be used to encrypt and decrypt a message. The sequence of events to encrypt and then decrypt @@ -41,19 +40,19 @@ public interface KeyCrypter { EncryptionType getUnderstoodEncryptionType(); /** - * Create a KeyParameter (which typically contains an AES key) + * Create an AESKey (which typically contains an AES key) * @param password - * @return KeyParameter The KeyParameter which typically contains the AES key to use for encrypting and decrypting + * @return AESKey which typically contains the AES key to use for encrypting and decrypting * @throws KeyCrypterException */ - KeyParameter deriveKey(CharSequence password) throws KeyCrypterException; + AesKey deriveKey(CharSequence password) throws KeyCrypterException; /** * Decrypt the provided encrypted bytes, converting them into unencrypted bytes. * * @throws KeyCrypterException if decryption was unsuccessful. */ - byte[] decrypt(EncryptedData encryptedBytesToDecode, KeyParameter aesKey) throws KeyCrypterException; + byte[] decrypt(EncryptedData encryptedBytesToDecode, AesKey aesKey) throws KeyCrypterException; /** * Encrypt the supplied bytes, converting them into ciphertext. @@ -61,5 +60,5 @@ public interface KeyCrypter { * @return encryptedPrivateKey An encryptedPrivateKey containing the encrypted bytes and an initialisation vector. * @throws KeyCrypterException if encryption was unsuccessful */ - EncryptedData encrypt(byte[] plainBytes, KeyParameter aesKey) throws KeyCrypterException; + EncryptedData encrypt(byte[] plainBytes, AesKey aesKey) throws KeyCrypterException; } diff --git a/core/src/main/java/org/bitcoinj/crypto/KeyCrypterScrypt.java b/core/src/main/java/org/bitcoinj/crypto/KeyCrypterScrypt.java index 3369c8f96..c7f0ab138 100644 --- a/core/src/main/java/org/bitcoinj/crypto/KeyCrypterScrypt.java +++ b/core/src/main/java/org/bitcoinj/crypto/KeyCrypterScrypt.java @@ -135,11 +135,11 @@ public class KeyCrypterScrypt implements KeyCrypter { * This is a very slow operation compared to encrypt/ decrypt so it is normally worth caching the result. * * @param password The password to use in key generation - * @return The KeyParameter containing the created AES key + * @return The AesKey containing the created AES key * @throws KeyCrypterException */ @Override - public KeyParameter deriveKey(CharSequence password) throws KeyCrypterException { + public AesKey deriveKey(CharSequence password) throws KeyCrypterException { byte[] passwordBytes = null; try { passwordBytes = convertToByteArray(password); @@ -155,7 +155,7 @@ public class KeyCrypterScrypt implements KeyCrypter { Instant start = TimeUtils.currentTime(); byte[] keyBytes = SCrypt.generate(passwordBytes, salt, (int) scryptParameters.getN(), scryptParameters.getR(), scryptParameters.getP(), KEY_LENGTH); log.info("Deriving key took {} ms for {}.", TimeUtils.elapsedTime(start).toMillis(), scryptParametersString()); - return new KeyParameter(keyBytes); + return new AesKey(keyBytes); } catch (Exception e) { throw new KeyCrypterException("Could not generate key from password and salt.", e); } finally { @@ -170,7 +170,7 @@ public class KeyCrypterScrypt implements KeyCrypter { * Password based encryption using AES - CBC 256 bits. */ @Override - public EncryptedData encrypt(byte[] plainBytes, KeyParameter aesKey) throws KeyCrypterException { + public EncryptedData encrypt(byte[] plainBytes, AesKey aesKey) throws KeyCrypterException { checkNotNull(plainBytes); checkNotNull(aesKey); @@ -179,7 +179,7 @@ public class KeyCrypterScrypt implements KeyCrypter { byte[] iv = new byte[BLOCK_LENGTH]; secureRandom.nextBytes(iv); - ParametersWithIV keyWithIv = new ParametersWithIV(aesKey, iv); + ParametersWithIV keyWithIv = new ParametersWithIV(new KeyParameter(aesKey.bytes()), iv); // Encrypt using AES. BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine())); @@ -203,12 +203,12 @@ public class KeyCrypterScrypt implements KeyCrypter { * @throws KeyCrypterException if bytes could not be decrypted */ @Override - public byte[] decrypt(EncryptedData dataToDecrypt, KeyParameter aesKey) throws KeyCrypterException { + public byte[] decrypt(EncryptedData dataToDecrypt, AesKey aesKey) throws KeyCrypterException { checkNotNull(dataToDecrypt); checkNotNull(aesKey); try { - ParametersWithIV keyWithIv = new ParametersWithIV(new KeyParameter(aesKey.getKey()), dataToDecrypt.initialisationVector); + ParametersWithIV keyWithIv = new ParametersWithIV(new KeyParameter(aesKey.bytes()), dataToDecrypt.initialisationVector); // Decrypt the message. BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine())); diff --git a/core/src/main/java/org/bitcoinj/wallet/BasicKeyChain.java b/core/src/main/java/org/bitcoinj/wallet/BasicKeyChain.java index 64ec406e3..f69e940c6 100644 --- a/core/src/main/java/org/bitcoinj/wallet/BasicKeyChain.java +++ b/core/src/main/java/org/bitcoinj/wallet/BasicKeyChain.java @@ -18,6 +18,7 @@ package org.bitcoinj.wallet; import com.google.protobuf.ByteString; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.core.BloomFilter; import org.bitcoinj.crypto.ECKey; import org.bitcoinj.core.NetworkParameters; @@ -29,12 +30,10 @@ import org.bitcoinj.crypto.KeyCrypterScrypt; import org.bitcoinj.utils.ListenerRegistration; import org.bitcoinj.utils.Threading; import org.bitcoinj.wallet.listeners.KeyChainEventListener; -import org.bouncycastle.crypto.params.KeyParameter; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedList; @@ -462,7 +461,7 @@ public class BasicKeyChain implements EncryptableKeyChain { /** * Convenience wrapper around {@link #toEncrypted(KeyCrypter, - * org.bouncycastle.crypto.params.KeyParameter)} which uses the default Scrypt key derivation algorithm and + * AesKey)} which uses the default Scrypt key derivation algorithm and * parameters, derives a key from the given password and returns the created key. */ @Override @@ -470,7 +469,7 @@ public class BasicKeyChain implements EncryptableKeyChain { checkNotNull(password); checkArgument(password.length() > 0); KeyCrypter scrypt = new KeyCrypterScrypt(); - KeyParameter derivedKey = scrypt.deriveKey(password); + AesKey derivedKey = scrypt.deriveKey(password); return toEncrypted(scrypt, derivedKey); } @@ -484,7 +483,7 @@ public class BasicKeyChain implements EncryptableKeyChain { * @throws KeyCrypterException Thrown if the wallet encryption fails. If so, the wallet state is unchanged. */ @Override - public BasicKeyChain toEncrypted(KeyCrypter keyCrypter, KeyParameter aesKey) { + public BasicKeyChain toEncrypted(KeyCrypter keyCrypter, AesKey aesKey) { lock.lock(); try { checkNotNull(keyCrypter); @@ -513,12 +512,12 @@ public class BasicKeyChain implements EncryptableKeyChain { @Override public BasicKeyChain toDecrypted(CharSequence password) { checkNotNull(keyCrypter, "Wallet is already decrypted"); - KeyParameter aesKey = keyCrypter.deriveKey(password); + AesKey aesKey = keyCrypter.deriveKey(password); return toDecrypted(aesKey); } @Override - public BasicKeyChain toDecrypted(KeyParameter aesKey) { + public BasicKeyChain toDecrypted(AesKey aesKey) { lock.lock(); try { checkState(keyCrypter != null, "Wallet is already decrypted"); @@ -555,7 +554,7 @@ public class BasicKeyChain implements EncryptableKeyChain { * @return true if AES key supplied can decrypt the first encrypted private key in the wallet, false otherwise. */ @Override - public boolean checkAESKey(KeyParameter aesKey) { + public boolean checkAESKey(AesKey aesKey) { lock.lock(); try { // If no keys then cannot decrypt. @@ -652,7 +651,7 @@ public class BasicKeyChain implements EncryptableKeyChain { } } - public String toString(boolean includePrivateKeys, @Nullable KeyParameter aesKey, NetworkParameters params) { + public String toString(boolean includePrivateKeys, @Nullable AesKey aesKey, NetworkParameters params) { final StringBuilder builder = new StringBuilder(); List keys = getKeys(); Collections.sort(keys, ECKey.AGE_COMPARATOR); diff --git a/core/src/main/java/org/bitcoinj/wallet/DecryptingKeyBag.java b/core/src/main/java/org/bitcoinj/wallet/DecryptingKeyBag.java index 2d5745e04..10af53e16 100644 --- a/core/src/main/java/org/bitcoinj/wallet/DecryptingKeyBag.java +++ b/core/src/main/java/org/bitcoinj/wallet/DecryptingKeyBag.java @@ -17,8 +17,8 @@ package org.bitcoinj.wallet; import org.bitcoinj.base.ScriptType; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.crypto.ECKey; -import org.bouncycastle.crypto.params.KeyParameter; import javax.annotation.Nullable; import java.util.ArrayList; @@ -33,9 +33,9 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public class DecryptingKeyBag implements KeyBag { protected final KeyBag target; - protected final KeyParameter aesKey; + protected final AesKey aesKey; - public DecryptingKeyBag(KeyBag target, @Nullable KeyParameter aesKey) { + public DecryptingKeyBag(KeyBag target, @Nullable AesKey aesKey) { this.target = checkNotNull(target); this.aesKey = aesKey; } diff --git a/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java b/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java index 6ce7eb2f2..f8e08dba6 100644 --- a/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java +++ b/core/src/main/java/org/bitcoinj/wallet/DeterministicKeyChain.java @@ -21,6 +21,7 @@ import com.google.protobuf.ByteString; import org.bitcoinj.base.Network; import org.bitcoinj.base.ScriptType; import org.bitcoinj.base.internal.TimeUtils; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.base.utils.ByteUtils; import org.bitcoinj.base.internal.StreamUtils; import org.bitcoinj.core.BloomFilter; @@ -42,7 +43,6 @@ import org.bitcoinj.script.Script; import org.bitcoinj.utils.ListenerRegistration; import org.bitcoinj.utils.Threading; import org.bitcoinj.wallet.listeners.KeyChainEventListener; -import org.bouncycastle.crypto.params.KeyParameter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -401,12 +401,12 @@ public class DeterministicKeyChain implements EncryptableKeyChain { } /** - * For use in encryption when {@link #toEncrypted(KeyCrypter, KeyParameter)} is called, so that + * For use in encryption when {@link #toEncrypted(KeyCrypter, AesKey)} is called, so that * subclasses can override that method and create an instance of the right class. * * See also {@link #makeKeyChainFromSeed(DeterministicSeed, List, ScriptType)} */ - protected DeterministicKeyChain(KeyCrypter crypter, KeyParameter aesKey, DeterministicKeyChain chain) { + protected DeterministicKeyChain(KeyCrypter crypter, AesKey aesKey, DeterministicKeyChain chain) { // Can't encrypt a watching chain. checkNotNull(chain.rootKey); checkNotNull(chain.seed); @@ -453,7 +453,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain { return outputScriptType; } - private DeterministicKey encryptNonLeaf(KeyParameter aesKey, DeterministicKeyChain chain, + private DeterministicKey encryptNonLeaf(AesKey aesKey, DeterministicKeyChain chain, DeterministicKey parent, List path) { DeterministicKey key = chain.hierarchy.get(path, false, false); key = key.encrypt(checkNotNull(basicKeyChain.getKeyCrypter()), aesKey, parent); @@ -1017,12 +1017,12 @@ public class DeterministicKeyChain implements EncryptableKeyChain { checkState(seed != null, "Attempt to encrypt a watching chain."); checkState(!seed.isEncrypted()); KeyCrypter scrypt = new KeyCrypterScrypt(); - KeyParameter derivedKey = scrypt.deriveKey(password); + AesKey derivedKey = scrypt.deriveKey(password); return toEncrypted(scrypt, derivedKey); } @Override - public DeterministicKeyChain toEncrypted(KeyCrypter keyCrypter, KeyParameter aesKey) { + public DeterministicKeyChain toEncrypted(KeyCrypter keyCrypter, AesKey aesKey) { return new DeterministicKeyChain(keyCrypter, aesKey, this); } @@ -1032,12 +1032,12 @@ public class DeterministicKeyChain implements EncryptableKeyChain { checkArgument(password.length() > 0); KeyCrypter crypter = getKeyCrypter(); checkState(crypter != null, "Chain not encrypted"); - KeyParameter derivedKey = crypter.deriveKey(password); + AesKey derivedKey = crypter.deriveKey(password); return toDecrypted(derivedKey); } @Override - public DeterministicKeyChain toDecrypted(KeyParameter aesKey) { + public DeterministicKeyChain toDecrypted(AesKey aesKey) { checkState(getKeyCrypter() != null, "Key chain not encrypted"); checkState(seed != null, "Can't decrypt a watching chain"); checkState(seed.isEncrypted()); @@ -1080,7 +1080,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain { } @Override - public boolean checkAESKey(KeyParameter aesKey) { + public boolean checkAESKey(AesKey aesKey) { checkState(rootKey != null, "Can't check password for a watching chain"); checkNotNull(aesKey); checkState(getKeyCrypter() != null, "Key chain not encrypted"); @@ -1422,7 +1422,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain { return helper.toString(); } - public String toString(boolean includeLookahead, boolean includePrivateKeys, @Nullable KeyParameter aesKey, NetworkParameters params) { + public String toString(boolean includeLookahead, boolean includePrivateKeys, @Nullable AesKey aesKey, NetworkParameters params) { final DeterministicKey watchingKey = getWatchingKey(); final StringBuilder builder = new StringBuilder(); if (seed != null) { @@ -1451,7 +1451,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain { return builder.toString(); } - protected void formatAddresses(boolean includeLookahead, boolean includePrivateKeys, @Nullable KeyParameter aesKey, + protected void formatAddresses(boolean includeLookahead, boolean includePrivateKeys, @Nullable AesKey aesKey, NetworkParameters params, StringBuilder builder) { for (DeterministicKey key : getKeys(includeLookahead, true)) { String comment = null; diff --git a/core/src/main/java/org/bitcoinj/wallet/DeterministicSeed.java b/core/src/main/java/org/bitcoinj/wallet/DeterministicSeed.java index cd9193087..dff60bacc 100644 --- a/core/src/main/java/org/bitcoinj/wallet/DeterministicSeed.java +++ b/core/src/main/java/org/bitcoinj/wallet/DeterministicSeed.java @@ -20,12 +20,12 @@ package org.bitcoinj.wallet; import com.google.common.base.MoreObjects; import org.bitcoinj.base.internal.TimeUtils; import org.bitcoinj.base.internal.InternalUtils; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.crypto.EncryptableItem; import org.bitcoinj.crypto.EncryptedData; import org.bitcoinj.crypto.KeyCrypter; import org.bitcoinj.crypto.MnemonicCode; import org.bitcoinj.crypto.MnemonicException; -import org.bouncycastle.crypto.params.KeyParameter; import javax.annotation.Nullable; import java.nio.charset.StandardCharsets; @@ -193,7 +193,7 @@ public class DeterministicSeed implements EncryptableItem { this.creationTimeSeconds = creationTimeSeconds; } - public DeterministicSeed encrypt(KeyCrypter keyCrypter, KeyParameter aesKey) { + public DeterministicSeed encrypt(KeyCrypter keyCrypter, AesKey aesKey) { checkState(encryptedMnemonicCode == null, "Trying to encrypt seed twice"); checkState(mnemonicCode != null, "Mnemonic missing so cannot encrypt"); EncryptedData encryptedMnemonic = keyCrypter.encrypt(getMnemonicAsBytes(), aesKey); @@ -205,7 +205,7 @@ public class DeterministicSeed implements EncryptableItem { return getMnemonicString().getBytes(StandardCharsets.UTF_8); } - public DeterministicSeed decrypt(KeyCrypter crypter, String passphrase, KeyParameter aesKey) { + public DeterministicSeed decrypt(KeyCrypter crypter, String passphrase, AesKey aesKey) { checkState(isEncrypted()); checkNotNull(encryptedMnemonicCode); List mnemonic = decodeMnemonicCode(crypter.decrypt(encryptedMnemonicCode, aesKey)); diff --git a/core/src/main/java/org/bitcoinj/wallet/EncryptableKeyChain.java b/core/src/main/java/org/bitcoinj/wallet/EncryptableKeyChain.java index fe7d91791..77cb58ed7 100644 --- a/core/src/main/java/org/bitcoinj/wallet/EncryptableKeyChain.java +++ b/core/src/main/java/org/bitcoinj/wallet/EncryptableKeyChain.java @@ -16,10 +16,10 @@ package org.bitcoinj.wallet; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.crypto.KeyCrypter; import org.bitcoinj.crypto.KeyCrypterException; import org.bitcoinj.crypto.KeyCrypterScrypt; -import org.bouncycastle.crypto.params.KeyParameter; import javax.annotation.Nullable; @@ -29,7 +29,7 @@ import javax.annotation.Nullable; public interface EncryptableKeyChain extends KeyChain { /** * Takes the given password, which should be strong, derives a key from it and then invokes - * {@link #toEncrypted(KeyCrypter, KeyParameter)} with + * {@link #toEncrypted(KeyCrypter, AesKey)} with * {@link KeyCrypterScrypt} as the crypter. * * @return The derived key, in case you wish to cache it for future use. @@ -40,10 +40,10 @@ public interface EncryptableKeyChain extends KeyChain { * Returns a new keychain holding identical/cloned keys to this chain, but encrypted under the given key. * Old keys and keychains remain valid and so you should ensure you don't accidentally hold references to them. */ - EncryptableKeyChain toEncrypted(KeyCrypter keyCrypter, KeyParameter aesKey); + EncryptableKeyChain toEncrypted(KeyCrypter keyCrypter, AesKey aesKey); /** - * Decrypts the key chain with the given password. See {@link #toDecrypted(KeyParameter)} + * Decrypts the key chain with the given password. See {@link #toDecrypted(AesKey)} * for details. */ EncryptableKeyChain toDecrypted(CharSequence password); @@ -57,10 +57,10 @@ public interface EncryptableKeyChain extends KeyChain { * create from a password) * @throws KeyCrypterException Thrown if the wallet decryption fails. If so, the wallet state is unchanged. */ - EncryptableKeyChain toDecrypted(KeyParameter aesKey); + EncryptableKeyChain toDecrypted(AesKey aesKey); boolean checkPassword(CharSequence password); - boolean checkAESKey(KeyParameter aesKey); + boolean checkAESKey(AesKey aesKey); /** Returns the key crypter used by this key chain, or null if it's not encrypted. */ @Nullable diff --git a/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java b/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java index 26d28de43..ce7c0c1e4 100644 --- a/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java +++ b/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java @@ -20,6 +20,7 @@ package org.bitcoinj.wallet; import com.google.protobuf.ByteString; import org.bitcoinj.base.BitcoinNetwork; import org.bitcoinj.base.Address; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.core.BloomFilter; import org.bitcoinj.crypto.ECKey; import org.bitcoinj.base.LegacyAddress; @@ -36,7 +37,6 @@ import org.bitcoinj.utils.ListenerRegistration; import org.bitcoinj.utils.Threading; import org.bitcoinj.wallet.listeners.CurrentKeyChangeEventListener; import org.bitcoinj.wallet.listeners.KeyChainEventListener; -import org.bouncycastle.crypto.params.KeyParameter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,7 +71,7 @@ import static com.google.common.base.Preconditions.checkState; * (see {@link #getActiveKeyChain(ScriptType, long)}) are meant as fallback for if a sender doesn't understand a * certain new script type (e.g. P2WPKH which comes with the new Bech32 address format). Active keychains * share the same seed, so that upgrading the wallet - * (see {@link #upgradeToDeterministic(ScriptType, KeyChainGroupStructure, long, KeyParameter)}) to understand + * (see {@link #upgradeToDeterministic(ScriptType, KeyChainGroupStructure, long, AesKey)}) to understand * a new script type doesn't require a fresh backup.

* *

If a key rotation time is set, it may be necessary to add a new DeterministicKeyChain with a fresh seed @@ -569,7 +569,7 @@ public class KeyChainGroup implements KeyBag { return checkAESKey(keyCrypter.deriveKey(password)); } - public boolean checkAESKey(KeyParameter aesKey) { + public boolean checkAESKey(AesKey aesKey) { checkState(keyCrypter != null, "Not encrypted"); if (basic.numKeys() > 0) return basic.checkAESKey(aesKey); @@ -577,7 +577,7 @@ public class KeyChainGroup implements KeyBag { } /** Imports the given unencrypted keys into the basic chain, encrypting them along the way with the given key. */ - public int importKeysAndEncrypt(final List keys, KeyParameter aesKey) { + public int importKeysAndEncrypt(final List keys, AesKey aesKey) { // TODO: Firstly check if the aes key can decrypt any of the existing keys successfully. checkState(keyCrypter != null, "Not encrypted"); LinkedList encryptedKeys = new LinkedList<>(); @@ -756,7 +756,7 @@ public class KeyChainGroup implements KeyBag { * leaving the group unchanged. * @throws DeterministicUpgradeRequiredException Thrown if there are random keys but no HD chain. */ - public void encrypt(KeyCrypter keyCrypter, KeyParameter aesKey) { + public void encrypt(KeyCrypter keyCrypter, AesKey aesKey) { checkNotNull(keyCrypter); checkNotNull(aesKey); checkState((chains != null && !chains.isEmpty()) || basic.numKeys() != 0, "can't encrypt entirely empty wallet"); @@ -783,7 +783,7 @@ public class KeyChainGroup implements KeyBag { * * @throws org.bitcoinj.crypto.KeyCrypterException Thrown if the wallet decryption fails for some reason, leaving the group unchanged. */ - public void decrypt(KeyParameter aesKey) { + public void decrypt(AesKey aesKey) { checkNotNull(aesKey); BasicKeyChain newBasic = basic.toDecrypted(aesKey); @@ -1011,7 +1011,7 @@ public class KeyChainGroup implements KeyBag { * and you should provide the users encryption key. */ public void upgradeToDeterministic(ScriptType preferredScriptType, KeyChainGroupStructure structure, - @Nullable Instant keyRotationTime, @Nullable KeyParameter aesKey) + @Nullable Instant keyRotationTime, @Nullable AesKey aesKey) throws DeterministicUpgradeRequiresPassword { checkState(supportsDeterministicChains(), "doesn't support deterministic chains"); checkNotNull(structure); @@ -1038,16 +1038,16 @@ public class KeyChainGroup implements KeyBag { } } - /** @deprecated use {@link #upgradeToDeterministic(ScriptType, KeyChainGroupStructure, Instant, KeyParameter)} */ + /** @deprecated use {@link #upgradeToDeterministic(ScriptType, KeyChainGroupStructure, Instant, AesKey)} */ @Deprecated public void upgradeToDeterministic(ScriptType preferredScriptType, KeyChainGroupStructure structure, - long keyRotationTimeSecs, @Nullable KeyParameter aesKey) { + long keyRotationTimeSecs, @Nullable AesKey aesKey) { Instant keyRotationTime = keyRotationTimeSecs > 0 ? Instant.ofEpochSecond(keyRotationTimeSecs) : null; upgradeToDeterministic(preferredScriptType, structure, keyRotationTime, aesKey); } /** - * Returns true if a call to {@link #upgradeToDeterministic(ScriptType, KeyChainGroupStructure, long, KeyParameter)} is required + * Returns true if a call to {@link #upgradeToDeterministic(ScriptType, KeyChainGroupStructure, long, AesKey)} is required * in order to have an active deterministic keychain of the desired script type. */ public boolean isDeterministicUpgradeRequired(ScriptType preferredScriptType, @Nullable Instant keyRotationTime) { @@ -1108,7 +1108,7 @@ public class KeyChainGroup implements KeyBag { } } - public String toString(boolean includeLookahead, boolean includePrivateKeys, @Nullable KeyParameter aesKey) { + public String toString(boolean includeLookahead, boolean includePrivateKeys, @Nullable AesKey aesKey) { final StringBuilder builder = new StringBuilder(); if (basic != null) builder.append(basic.toString(includePrivateKeys, aesKey, params)); diff --git a/core/src/main/java/org/bitcoinj/wallet/MarriedKeyChain.java b/core/src/main/java/org/bitcoinj/wallet/MarriedKeyChain.java index 0924c643a..6ac89206e 100644 --- a/core/src/main/java/org/bitcoinj/wallet/MarriedKeyChain.java +++ b/core/src/main/java/org/bitcoinj/wallet/MarriedKeyChain.java @@ -19,6 +19,7 @@ package org.bitcoinj.wallet; import com.google.common.collect.Lists; import com.google.protobuf.ByteString; import org.bitcoinj.base.ScriptType; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.base.utils.ByteUtils; import org.bitcoinj.core.BloomFilter; import org.bitcoinj.crypto.ECKey; @@ -28,7 +29,6 @@ import org.bitcoinj.crypto.DeterministicKey; import org.bitcoinj.crypto.KeyCrypter; import org.bitcoinj.script.Script; import org.bitcoinj.script.ScriptBuilder; -import org.bouncycastle.crypto.params.KeyParameter; import javax.annotation.Nullable; import java.util.ArrayList; @@ -237,7 +237,7 @@ public class MarriedKeyChain extends DeterministicKeyChain { } @Override - protected void formatAddresses(boolean includeLookahead, boolean includePrivateKeys, @Nullable KeyParameter aesKey, + protected void formatAddresses(boolean includeLookahead, boolean includePrivateKeys, @Nullable AesKey aesKey, NetworkParameters params, StringBuilder builder) { for (DeterministicKeyChain followingChain : followingKeyChains) builder.append("Following chain: ").append(followingChain.getWatchingKey().serializePubB58(params.network())) diff --git a/core/src/main/java/org/bitcoinj/wallet/SendRequest.java b/core/src/main/java/org/bitcoinj/wallet/SendRequest.java index 36349ff18..3925b1975 100644 --- a/core/src/main/java/org/bitcoinj/wallet/SendRequest.java +++ b/core/src/main/java/org/bitcoinj/wallet/SendRequest.java @@ -21,6 +21,7 @@ import com.google.common.base.MoreObjects; import org.bitcoin.protocols.payments.Protos.PaymentDetails; import org.bitcoinj.base.Address; import org.bitcoinj.base.Coin; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.core.Context; import org.bitcoinj.crypto.ECKey; import org.bitcoinj.core.NetworkParameters; @@ -29,7 +30,6 @@ import org.bitcoinj.core.TransactionOutput; import org.bitcoinj.utils.ExchangeRate; import org.bitcoinj.wallet.KeyChain.KeyPurpose; import org.bitcoinj.wallet.Wallet.MissingSigsMode; -import org.bouncycastle.crypto.params.KeyParameter; import static com.google.common.base.Preconditions.checkNotNull; @@ -109,7 +109,7 @@ public class SendRequest { * If null then no decryption will be performed and if decryption is required an exception will be thrown. * You can get this from a password by doing wallet.getKeyCrypter().deriveKey(password). */ - public KeyParameter aesKey = null; + public AesKey aesKey = null; /** * If not null, the {@link CoinSelector} to use instead of the wallets default. Coin selectors are diff --git a/core/src/main/java/org/bitcoinj/wallet/Wallet.java b/core/src/main/java/org/bitcoinj/wallet/Wallet.java index 12f600ec7..eed4cb3b7 100644 --- a/core/src/main/java/org/bitcoinj/wallet/Wallet.java +++ b/core/src/main/java/org/bitcoinj/wallet/Wallet.java @@ -30,6 +30,7 @@ import org.bitcoinj.base.exceptions.AddressFormatException; import org.bitcoinj.base.internal.PlatformUtils; import org.bitcoinj.base.internal.TimeUtils; import org.bitcoinj.base.internal.StreamUtils; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.core.AbstractBlockChain; import org.bitcoinj.base.Address; import org.bitcoinj.base.Base58; @@ -98,7 +99,6 @@ import org.bitcoinj.wallet.listeners.WalletChangeEventListener; import org.bitcoinj.wallet.listeners.WalletCoinsReceivedEventListener; import org.bitcoinj.wallet.listeners.WalletCoinsSentEventListener; import org.bitcoinj.wallet.listeners.WalletReorganizeEventListener; -import org.bouncycastle.crypto.params.KeyParameter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -792,7 +792,7 @@ public class Wallet extends BaseTaggableObject * to do this will result in an exception being thrown. For non-encrypted wallets, the upgrade will be done for * you automatically the first time a new key is requested (this happens when spending due to the change address). */ - public void upgradeToDeterministic(ScriptType outputScriptType, @Nullable KeyParameter aesKey) + public void upgradeToDeterministic(ScriptType outputScriptType, @Nullable AesKey aesKey) throws DeterministicUpgradeRequiresPassword { upgradeToDeterministic(outputScriptType, KeyChainGroupStructure.BIP32, aesKey); } @@ -805,7 +805,7 @@ public class Wallet extends BaseTaggableObject * you automatically the first time a new key is requested (this happens when spending due to the change address). */ public void upgradeToDeterministic(ScriptType outputScriptType, KeyChainGroupStructure structure, - @Nullable KeyParameter aesKey) throws DeterministicUpgradeRequiresPassword { + @Nullable AesKey aesKey) throws DeterministicUpgradeRequiresPassword { keyChainGroupLock.lock(); try { Instant keyRotationTime = vKeyRotationTime; @@ -817,7 +817,7 @@ public class Wallet extends BaseTaggableObject /** * Returns true if the wallet contains random keys and no HD chains, in which case you should call - * {@link #upgradeToDeterministic(ScriptType, KeyParameter)} before attempting to do anything + * {@link #upgradeToDeterministic(ScriptType, AesKey)} before attempting to do anything * that would require a new address or key. */ public boolean isDeterministicUpgradeRequired(ScriptType outputScriptType) { @@ -945,7 +945,7 @@ public class Wallet extends BaseTaggableObject } /** Takes a list of keys and an AES key, then encrypts and imports them in one step using the current keycrypter. */ - public int importKeysAndEncrypt(final List keys, KeyParameter aesKey) { + public int importKeysAndEncrypt(final List keys, AesKey aesKey) { keyChainGroupLock.lock(); try { checkNoDeterministicKeys(keys); @@ -1341,7 +1341,7 @@ public class Wallet extends BaseTaggableObject /** * Convenience wrapper around {@link Wallet#encrypt(KeyCrypter, - * org.bouncycastle.crypto.params.KeyParameter)} which uses the default Scrypt key derivation algorithm and + * AesKey)} which uses the default Scrypt key derivation algorithm and * parameters to derive a key from the given password. */ public void encrypt(CharSequence password) { @@ -1363,7 +1363,7 @@ public class Wallet extends BaseTaggableObject * @param aesKey AES key to use (normally created using KeyCrypter#deriveKey and cached as it is time consuming to create from a password) * @throws KeyCrypterException Thrown if the wallet encryption fails. If so, the wallet state is unchanged. */ - public void encrypt(KeyCrypter keyCrypter, KeyParameter aesKey) { + public void encrypt(KeyCrypter keyCrypter, AesKey aesKey) { keyChainGroupLock.lock(); try { keyChainGroup.encrypt(keyCrypter, aesKey); @@ -1399,7 +1399,7 @@ public class Wallet extends BaseTaggableObject * @throws BadWalletEncryptionKeyException Thrown if the given aesKey is wrong. If so, the wallet state is unchanged. * @throws KeyCrypterException Thrown if the wallet decryption fails. If so, the wallet state is unchanged. */ - public void decrypt(KeyParameter aesKey) throws BadWalletEncryptionKeyException { + public void decrypt(AesKey aesKey) throws BadWalletEncryptionKeyException { keyChainGroupLock.lock(); try { keyChainGroup.decrypt(aesKey); @@ -1432,7 +1432,7 @@ public class Wallet extends BaseTaggableObject * * @return boolean true if AES key supplied can decrypt the first encrypted private key in the wallet, false otherwise. */ - public boolean checkAESKey(KeyParameter aesKey) { + public boolean checkAESKey(AesKey aesKey) { keyChainGroupLock.lock(); try { return keyChainGroup.checkAESKey(aesKey); @@ -1498,7 +1498,7 @@ public class Wallet extends BaseTaggableObject * @throws BadWalletEncryptionKeyException Thrown if the given currentAesKey is wrong. If so, the wallet state is unchanged. * @throws KeyCrypterException Thrown if the wallet decryption fails. If so, the wallet state is unchanged. */ - public void changeEncryptionKey(KeyCrypter keyCrypter, KeyParameter currentAesKey, KeyParameter newAesKey) throws BadWalletEncryptionKeyException { + public void changeEncryptionKey(KeyCrypter keyCrypter, AesKey currentAesKey, AesKey newAesKey) throws BadWalletEncryptionKeyException { keyChainGroupLock.lock(); try { decrypt(currentAesKey); @@ -3458,7 +3458,7 @@ public class Wallet extends BaseTaggableObject * @param chain If set, will be used to estimate lock times for block time-locked transactions. * @return Human-readable wallet debugging information */ - public String toString(boolean includeLookahead, boolean includePrivateKeys, @Nullable KeyParameter aesKey, + public String toString(boolean includeLookahead, boolean includePrivateKeys, @Nullable AesKey aesKey, boolean includeTransactions, boolean includeExtensions, @Nullable AbstractBlockChain chain) { lock.lock(); keyChainGroupLock.lock(); @@ -5318,7 +5318,7 @@ public class Wallet extends BaseTaggableObject *

* *

- * Once set up, calling {@link #doMaintenance(KeyParameter, boolean)} will create and possibly send rotation + * Once set up, calling {@link #doMaintenance(AesKey, boolean)} will create and possibly send rotation * transactions: but it won't be done automatically (because you might have to ask for the users password). This may * need to be repeated regularly in case new coins keep coming in on rotating addresses/keys. *

@@ -5392,7 +5392,7 @@ public class Wallet extends BaseTaggableObject * @return A list of transactions that the wallet just made/will make for internal maintenance. Might be empty. * @throws org.bitcoinj.wallet.DeterministicUpgradeRequiresPassword if key rotation requires the users password. */ - public ListenableCompletableFuture> doMaintenance(@Nullable KeyParameter aesKey, boolean signAndSend) + public ListenableCompletableFuture> doMaintenance(@Nullable AesKey aesKey, boolean signAndSend) throws DeterministicUpgradeRequiresPassword { return doMaintenance(KeyChainGroupStructure.BIP32, aesKey, signAndSend); } @@ -5413,7 +5413,7 @@ public class Wallet extends BaseTaggableObject * @throws org.bitcoinj.wallet.DeterministicUpgradeRequiresPassword if key rotation requires the users password. */ public ListenableCompletableFuture> doMaintenance(KeyChainGroupStructure structure, - @Nullable KeyParameter aesKey, boolean signAndSend) throws DeterministicUpgradeRequiresPassword { + @Nullable AesKey aesKey, boolean signAndSend) throws DeterministicUpgradeRequiresPassword { List txns; lock.lock(); keyChainGroupLock.lock(); @@ -5448,7 +5448,7 @@ public class Wallet extends BaseTaggableObject // Checks to see if any coins are controlled by rotating keys and if so, spends them. @GuardedBy("keyChainGroupLock") - private List maybeRotateKeys(KeyChainGroupStructure structure, @Nullable KeyParameter aesKey, + private List maybeRotateKeys(KeyChainGroupStructure structure, @Nullable AesKey aesKey, boolean sign) throws DeterministicUpgradeRequiresPassword { checkState(lock.isHeldByCurrentThread()); checkState(keyChainGroupLock.isHeldByCurrentThread()); @@ -5525,7 +5525,7 @@ public class Wallet extends BaseTaggableObject } @Nullable - private Transaction rekeyOneBatch(Instant time, @Nullable KeyParameter aesKey, List others, boolean sign) { + private Transaction rekeyOneBatch(Instant time, @Nullable AesKey aesKey, List others, boolean sign) { lock.lock(); try { // Build the transaction using some custom logic for our special needs. Last parameter to diff --git a/core/src/test/java/org/bitcoinj/crypto/ChildKeyDerivationTest.java b/core/src/test/java/org/bitcoinj/crypto/ChildKeyDerivationTest.java index 33535e888..90a1e2cec 100644 --- a/core/src/test/java/org/bitcoinj/crypto/ChildKeyDerivationTest.java +++ b/core/src/test/java/org/bitcoinj/crypto/ChildKeyDerivationTest.java @@ -22,7 +22,6 @@ import org.bitcoinj.base.Sha256Hash; import static org.bitcoinj.base.BitcoinNetwork.MAINNET; import static org.bitcoinj.base.BitcoinNetwork.TESTNET; -import org.bouncycastle.crypto.params.KeyParameter; import org.junit.Test; import org.bitcoinj.base.utils.ByteUtils; @@ -172,7 +171,7 @@ public class ChildKeyDerivationTest { // Check that encrypting a parent key in the hierarchy and then deriving from it yields a DeterministicKey // with no private key component, and that the private key bytes are derived on demand. KeyCrypter scrypter = new KeyCrypterScrypt(SCRYPT_ITERATIONS); - KeyParameter aesKey = scrypter.deriveKey("we never went to the moon"); + AesKey aesKey = scrypter.deriveKey("we never went to the moon"); DeterministicKey key1 = HDKeyDerivation.createMasterPrivateKey("it was all a hoax".getBytes()); DeterministicKey encryptedKey1 = key1.encrypt(scrypter, aesKey, null); diff --git a/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java b/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java index 772535176..19dc8ad2d 100644 --- a/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java +++ b/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java @@ -30,7 +30,6 @@ import org.bitcoinj.core.Transaction; import org.bitcoinj.crypto.ECKey.ECDSASignature; import org.bitcoinj.crypto.internal.CryptoUtils; import org.bitcoinj.base.internal.FutureUtils; -import org.bouncycastle.crypto.params.KeyParameter; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; @@ -48,7 +47,6 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import static com.google.common.base.Preconditions.checkNotNull; -import org.bitcoinj.base.utils.ByteUtils; import static org.bitcoinj.base.utils.ByteUtils.reverseBytes; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -415,7 +413,7 @@ public class ECKeyTest { @Test public void keyRecoveryWithEncryptedKey() { ECKey unencryptedKey = new ECKey(); - KeyParameter aesKey = keyCrypter.deriveKey(PASSWORD1); + AesKey aesKey = keyCrypter.deriveKey(PASSWORD1); ECKey encryptedKey = unencryptedKey.encrypt(keyCrypter, aesKey); String message = "Goodbye Jupiter!"; diff --git a/core/src/test/java/org/bitcoinj/crypto/HDKeyDerivationTest.java b/core/src/test/java/org/bitcoinj/crypto/HDKeyDerivationTest.java index c7fd79c32..29dabbb28 100644 --- a/core/src/test/java/org/bitcoinj/crypto/HDKeyDerivationTest.java +++ b/core/src/test/java/org/bitcoinj/crypto/HDKeyDerivationTest.java @@ -19,7 +19,6 @@ package org.bitcoinj.crypto; import org.bitcoinj.base.utils.ByteUtils; import org.bitcoinj.crypto.HDKeyDerivation.PublicDeriveMode; -import org.bouncycastle.crypto.params.KeyParameter; import org.junit.Test; import java.math.BigInteger; @@ -36,7 +35,7 @@ import static org.junit.Assert.fail; */ public class HDKeyDerivationTest { private static final KeyCrypterScrypt KEY_CRYPTER = new KeyCrypterScrypt(2); - private static final KeyParameter AES_KEY = KEY_CRYPTER.deriveKey("password"); + private static final AesKey AES_KEY = KEY_CRYPTER.deriveKey("password"); private static final ChildNumber CHILD_NUMBER = ChildNumber.ONE; private static final String EXPECTED_CHILD_CHAIN_CODE = "c4341fe988a2ae6240788c6b21df268b9286769915bed23c7649f263b3643ee8"; private static final String EXPECTED_CHILD_PRIVATE_KEY = "48516d403070bc93f5e4d78c984cf2d71fc9799293b4eeb3de4f88e3892f523d"; diff --git a/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java b/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java index d645caa0f..16cab4029 100644 --- a/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java +++ b/core/src/test/java/org/bitcoinj/wallet/DeterministicKeyChainTest.java @@ -22,6 +22,7 @@ import org.bitcoinj.base.Network; import org.bitcoinj.base.ScriptType; import org.bitcoinj.base.Address; import org.bitcoinj.base.internal.TimeUtils; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.core.BloomFilter; import org.bitcoinj.crypto.ECKey; import org.bitcoinj.base.LegacyAddress; @@ -34,7 +35,6 @@ import org.bitcoinj.crypto.HDPath; import org.bitcoinj.utils.BriefLogFormatter; import org.bitcoinj.utils.Threading; import org.bitcoinj.wallet.listeners.AbstractKeyChainEventListener; -import org.bouncycastle.crypto.params.KeyParameter; import org.junit.Before; import org.junit.Test; @@ -356,7 +356,7 @@ public class DeterministicKeyChainTest { assertFalse(key1.isEncrypted()); assertTrue(encKey1.isEncrypted()); assertEquals(encKey1.getPubKeyPoint(), key1.getPubKeyPoint()); - final KeyParameter aesKey = checkNotNull(encChain.getKeyCrypter()).deriveKey("open secret"); + final AesKey aesKey = checkNotNull(encChain.getKeyCrypter()).deriveKey("open secret"); encKey1.sign(Sha256Hash.ZERO_HASH, aesKey); encKey2.sign(Sha256Hash.ZERO_HASH, aesKey); assertTrue(encChain.checkAESKey(aesKey)); diff --git a/core/src/test/java/org/bitcoinj/wallet/KeyChainGroupTest.java b/core/src/test/java/org/bitcoinj/wallet/KeyChainGroupTest.java index 0d822d88c..46828e8eb 100644 --- a/core/src/test/java/org/bitcoinj/wallet/KeyChainGroupTest.java +++ b/core/src/test/java/org/bitcoinj/wallet/KeyChainGroupTest.java @@ -19,6 +19,7 @@ package org.bitcoinj.wallet; import org.bitcoinj.base.Address; import org.bitcoinj.base.internal.TimeUtils; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.core.BloomFilter; import org.bitcoinj.crypto.ECKey; import org.bitcoinj.core.NetworkParameters; @@ -33,7 +34,6 @@ import org.bitcoinj.utils.BriefLogFormatter; import org.bitcoinj.utils.Threading; import org.bitcoinj.wallet.KeyChain.KeyPurpose; import org.bitcoinj.wallet.listeners.KeyChainEventListener; -import org.bouncycastle.crypto.params.KeyParameter; import org.junit.Before; import org.junit.Test; @@ -60,7 +60,7 @@ public class KeyChainGroupTest { private static final String XPUB = "xpub68KFnj3bqUx1s7mHejLDBPywCAKdJEu1b49uniEEn2WSbHmZ7xbLqFTjJbtx1LUcAt1DwhoqWHmo2s5WMJp6wi38CiF2hYD49qVViKVvAoi"; private static final byte[] ENTROPY = Sha256Hash.hash("don't use a string seed like this in real life".getBytes()); private static final KeyCrypterScrypt KEY_CRYPTER = new KeyCrypterScrypt(2); - private static final KeyParameter AES_KEY = KEY_CRYPTER.deriveKey("password"); + private static final AesKey AES_KEY = KEY_CRYPTER.deriveKey("password"); private KeyChainGroup group; private DeterministicKey watchingAccountKey; diff --git a/core/src/test/java/org/bitcoinj/wallet/WalletTest.java b/core/src/test/java/org/bitcoinj/wallet/WalletTest.java index 466f7092e..7b349f5b4 100644 --- a/core/src/test/java/org/bitcoinj/wallet/WalletTest.java +++ b/core/src/test/java/org/bitcoinj/wallet/WalletTest.java @@ -21,6 +21,7 @@ import com.google.common.collect.Lists; import org.bitcoinj.base.BitcoinNetwork; import org.bitcoinj.base.ScriptType; import org.bitcoinj.base.internal.TimeUtils; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.base.utils.ByteUtils; import org.bitcoinj.core.AbstractBlockChain; import org.bitcoinj.base.Address; @@ -69,7 +70,6 @@ import org.bitcoinj.wallet.KeyChain.KeyPurpose; import org.bitcoinj.wallet.Protos.Wallet.EncryptionType; import org.bitcoinj.wallet.Wallet.BalanceType; import org.bitcoinj.wallet.WalletTransaction.Pool; -import org.bouncycastle.crypto.params.KeyParameter; import org.easymock.EasyMock; import org.junit.After; import org.junit.Before; @@ -87,7 +87,6 @@ import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Date; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -106,7 +105,6 @@ import static org.bitcoinj.base.Coin.MILLICOIN; import static org.bitcoinj.base.Coin.SATOSHI; import static org.bitcoinj.base.Coin.ZERO; import static org.bitcoinj.base.Coin.valueOf; -import org.bitcoinj.base.utils.ByteUtils; import static org.bitcoinj.testing.FakeTxBuilder.createFakeBlock; import static org.bitcoinj.testing.FakeTxBuilder.createFakeTx; import static org.bitcoinj.testing.FakeTxBuilder.createFakeTxWithoutChangeAddress; @@ -389,8 +387,8 @@ public class WalletTest extends TestWithWallet { if (encryptedWallet != null) { KeyCrypter keyCrypter = encryptedWallet.getKeyCrypter(); - KeyParameter aesKey = keyCrypter.deriveKey(PASSWORD1); - KeyParameter wrongAesKey = keyCrypter.deriveKey(WRONG_PASSWORD); + AesKey aesKey = keyCrypter.deriveKey(PASSWORD1); + AesKey wrongAesKey = keyCrypter.deriveKey(WRONG_PASSWORD); // Try to create a send with a fee but no password (this should fail). try { @@ -504,7 +502,7 @@ public class WalletTest extends TestWithWallet { assertEquals(1, txns.size()); } - private Wallet spendUnconfirmedChange(Wallet wallet, Transaction t2, KeyParameter aesKey) throws Exception { + private Wallet spendUnconfirmedChange(Wallet wallet, Transaction t2, AesKey aesKey) throws Exception { if (wallet.getTransactionSigners().size() == 1) // don't bother reconfiguring the p2sh wallet wallet = roundTrip(wallet); Coin v3 = valueOf(0, 50); @@ -1924,7 +1922,7 @@ public class WalletTest extends TestWithWallet { Wallet encryptedWallet = Wallet.createDeterministic(TESTNET, ScriptType.P2PKH); encryptedWallet.encrypt(PASSWORD1); KeyCrypter keyCrypter = encryptedWallet.getKeyCrypter(); - KeyParameter aesKey = keyCrypter.deriveKey(PASSWORD1); + AesKey aesKey = keyCrypter.deriveKey(PASSWORD1); assertEquals(EncryptionType.ENCRYPTED_SCRYPT_AES, encryptedWallet.getEncryptionType()); assertTrue(encryptedWallet.checkPassword(PASSWORD1)); @@ -1965,7 +1963,7 @@ public class WalletTest extends TestWithWallet { Wallet encryptedWallet = Wallet.createDeterministic(TESTNET, ScriptType.P2PKH); encryptedWallet.encrypt(PASSWORD1); KeyCrypter keyCrypter = encryptedWallet.getKeyCrypter(); - KeyParameter wrongAesKey = keyCrypter.deriveKey(WRONG_PASSWORD); + AesKey wrongAesKey = keyCrypter.deriveKey(WRONG_PASSWORD); // Check the wallet is currently encrypted assertEquals("Wallet is not an encrypted wallet", EncryptionType.ENCRYPTED_SCRYPT_AES, encryptedWallet.getEncryptionType()); @@ -1996,10 +1994,10 @@ public class WalletTest extends TestWithWallet { encryptedWallet.encrypt(PASSWORD1); KeyCrypter keyCrypter = encryptedWallet.getKeyCrypter(); - KeyParameter aesKey = keyCrypter.deriveKey(PASSWORD1); + AesKey aesKey = keyCrypter.deriveKey(PASSWORD1); CharSequence newPassword = "My name is Tom"; - KeyParameter newAesKey = keyCrypter.deriveKey(newPassword); + AesKey newAesKey = keyCrypter.deriveKey(newPassword); encryptedWallet.changeEncryptionKey(keyCrypter, aesKey, newAesKey); @@ -2012,7 +2010,7 @@ public class WalletTest extends TestWithWallet { Wallet encryptedWallet = Wallet.createDeterministic(TESTNET, ScriptType.P2PKH); encryptedWallet.encrypt(PASSWORD1); KeyCrypter keyCrypter = encryptedWallet.getKeyCrypter(); - KeyParameter aesKey = keyCrypter.deriveKey(PASSWORD1); + AesKey aesKey = keyCrypter.deriveKey(PASSWORD1); // Check the wallet is currently encrypted assertEquals("Wallet is not an encrypted wallet", EncryptionType.ENCRYPTED_SCRYPT_AES, encryptedWallet.getEncryptionType()); @@ -2071,7 +2069,7 @@ public class WalletTest extends TestWithWallet { Wallet encryptedWallet = Wallet.createDeterministic(TESTNET, ScriptType.P2PKH); encryptedWallet.encrypt(PASSWORD1); KeyCrypter keyCrypter = encryptedWallet.getKeyCrypter(); - KeyParameter aesKey = keyCrypter.deriveKey(PASSWORD1); + AesKey aesKey = keyCrypter.deriveKey(PASSWORD1); // Try added an ECKey that was encrypted with a differenct ScryptParameters (i.e. a non-homogenous key). // This is not allowed as the ScryptParameters is stored at the Wallet level. @@ -3247,7 +3245,7 @@ public class WalletTest extends TestWithWallet { assertFalse(wallet.isDeterministicUpgradeRequired(ScriptType.P2PKH)); assertTrue(wallet.isDeterministicUpgradeRequired(ScriptType.P2WPKH)); - KeyParameter aesKey = new KeyCrypterScrypt(SCRYPT_ITERATIONS).deriveKey("abc"); + AesKey aesKey = new KeyCrypterScrypt(SCRYPT_ITERATIONS).deriveKey("abc"); wallet.encrypt(new KeyCrypterScrypt(), aesKey); assertTrue(wallet.isEncrypted()); assertEquals(ScriptType.P2PKH, wallet.currentReceiveAddress().getOutputScriptType()); diff --git a/wallettemplate/src/main/java/org/bitcoinj/walletfx/utils/KeyDerivationTasks.java b/wallettemplate/src/main/java/org/bitcoinj/walletfx/utils/KeyDerivationTasks.java index c93dbbeef..d0ddf6719 100644 --- a/wallettemplate/src/main/java/org/bitcoinj/walletfx/utils/KeyDerivationTasks.java +++ b/wallettemplate/src/main/java/org/bitcoinj/walletfx/utils/KeyDerivationTasks.java @@ -16,13 +16,13 @@ package org.bitcoinj.walletfx.utils; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.crypto.KeyCrypterScrypt; import com.google.common.util.concurrent.Uninterruptibles; import javafx.beans.property.ReadOnlyDoubleProperty; import javafx.concurrent.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.bouncycastle.crypto.params.KeyParameter; import javax.annotation.*; import java.time.Duration; @@ -36,7 +36,7 @@ import static org.bitcoinj.walletfx.utils.GuiUtils.checkGuiThread; public class KeyDerivationTasks { private static final Logger log = LoggerFactory.getLogger(KeyDerivationTasks.class); - public final Task keyDerivationTask; + public final Task keyDerivationTask; public final ReadOnlyDoubleProperty progress; private final Task progressTask; @@ -46,11 +46,11 @@ public class KeyDerivationTasks { public KeyDerivationTasks(KeyCrypterScrypt scrypt, String password, @Nullable Duration targetTime) { keyDerivationTask = new Task<>() { @Override - protected KeyParameter call() throws Exception { + protected AesKey call() throws Exception { long start = System.currentTimeMillis(); try { log.info("Started key derivation"); - KeyParameter result = scrypt.deriveKey(password); + AesKey result = scrypt.deriveKey(password); timeTakenMsec = (int) (System.currentTimeMillis() - start); log.info("Key derivation done in {}ms", timeTakenMsec); return result; @@ -64,7 +64,7 @@ public class KeyDerivationTasks { // And the fake progress meter ... if the vals were calculated correctly progress bar should reach 100% // a brief moment after the keys were derived successfully. progressTask = new Task<>() { - private KeyParameter aesKey; + private AesKey aesKey; @Override protected Void call() throws Exception { @@ -102,6 +102,6 @@ public class KeyDerivationTasks { new Thread(progressTask, "Progress ticker").start(); } - protected void onFinish(KeyParameter aesKey, int timeTakenMsec) { + protected void onFinish(AesKey aesKey, int timeTakenMsec) { } } diff --git a/wallettemplate/src/main/java/wallettemplate/SendMoneyController.java b/wallettemplate/src/main/java/wallettemplate/SendMoneyController.java index 7dd393722..09186b5d4 100644 --- a/wallettemplate/src/main/java/wallettemplate/SendMoneyController.java +++ b/wallettemplate/src/main/java/wallettemplate/SendMoneyController.java @@ -19,6 +19,7 @@ package wallettemplate; import javafx.scene.layout.HBox; import org.bitcoinj.base.Address; import org.bitcoinj.base.Coin; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.core.*; import org.bitcoinj.crypto.ECKey; import org.bitcoinj.wallet.SendRequest; @@ -35,7 +36,6 @@ import javafx.scene.control.TextField; import org.bitcoinj.walletfx.application.WalletApplication; import org.bitcoinj.walletfx.overlay.OverlayController; import org.bitcoinj.walletfx.overlay.OverlayableStackPaneController; -import org.bouncycastle.crypto.params.KeyParameter; import org.bitcoinj.walletfx.controls.BitcoinAddressValidator; import org.bitcoinj.walletfx.utils.TextFieldValidator; import org.bitcoinj.walletfx.utils.WTUtils; @@ -58,7 +58,7 @@ public class SendMoneyController implements OverlayController> overlayUI; private Wallet.SendResult sendResult; - private KeyParameter aesKey; + private AesKey aesKey; @Override public void initOverlay(OverlayableStackPaneController overlayableStackPaneController, OverlayableStackPaneController.OverlayUI> ui) { diff --git a/wallettemplate/src/main/java/wallettemplate/WalletPasswordController.java b/wallettemplate/src/main/java/wallettemplate/WalletPasswordController.java index 3f8389c62..b6c691c92 100644 --- a/wallettemplate/src/main/java/wallettemplate/WalletPasswordController.java +++ b/wallettemplate/src/main/java/wallettemplate/WalletPasswordController.java @@ -17,6 +17,7 @@ package wallettemplate; import javafx.application.Platform; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.crypto.KeyCrypterScrypt; import com.google.common.primitives.Longs; import com.google.protobuf.ByteString; @@ -35,7 +36,6 @@ import org.bitcoinj.walletfx.overlay.OverlayController; import org.bitcoinj.walletfx.overlay.OverlayableStackPaneController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.bouncycastle.crypto.params.KeyParameter; import org.bitcoinj.walletfx.utils.KeyDerivationTasks; import java.time.Duration; @@ -61,7 +61,7 @@ public class WalletPasswordController implements OverlayController> overlayUI; - private SimpleObjectProperty aesKey = new SimpleObjectProperty<>(); + private SimpleObjectProperty aesKey = new SimpleObjectProperty<>(); @Override public void initOverlay(OverlayableStackPaneController overlayableStackPaneController, OverlayableStackPaneController.OverlayUI> ui) { @@ -86,7 +86,7 @@ public class WalletPasswordController implements OverlayController aesKeyProperty() { + public ReadOnlyObjectProperty aesKeyProperty() { return aesKey; } diff --git a/wallettemplate/src/main/java/wallettemplate/WalletSetPasswordController.java b/wallettemplate/src/main/java/wallettemplate/WalletSetPasswordController.java index 39d824bdd..781f1b48c 100644 --- a/wallettemplate/src/main/java/wallettemplate/WalletSetPasswordController.java +++ b/wallettemplate/src/main/java/wallettemplate/WalletSetPasswordController.java @@ -16,18 +16,17 @@ package wallettemplate; -import javafx.application.*; import javafx.event.*; import javafx.fxml.*; import javafx.scene.control.*; import javafx.scene.layout.*; +import org.bitcoinj.crypto.AesKey; import org.bitcoinj.crypto.*; import org.bitcoinj.wallet.*; import org.bitcoinj.walletfx.application.WalletApplication; import org.bitcoinj.walletfx.overlay.OverlayController; import org.bitcoinj.walletfx.overlay.OverlayableStackPaneController; import org.slf4j.*; -import org.bouncycastle.crypto.params.*; import com.google.protobuf.ByteString; @@ -124,7 +123,7 @@ public class WalletSetPasswordController implements OverlayController> overlayUI; - private KeyParameter aesKey; + private AesKey aesKey; @Override public void initOverlay(OverlayableStackPaneController overlayableStackPaneController, OverlayableStackPaneController.OverlayUI> ui) { @@ -70,7 +70,7 @@ public class WalletSettingsController implements OverlayController { + " to " + outputScriptType); return; } - KeyParameter aesKey = null; + AesKey aesKey = null; if (wallet.isEncrypted()) { aesKey = passwordToKey(true); if (aesKey == null) @@ -597,7 +596,7 @@ public class WalletTool implements Callable { } log.info("Setting wallet key rotation time to {}", rotationTimeSecs); wallet.setKeyRotationTime(rotationTimeSecs); - KeyParameter aesKey = null; + AesKey aesKey = null; if (wallet.isEncrypted()) { aesKey = passwordToKey(true); if (aesKey == null) @@ -1157,7 +1156,7 @@ public class WalletTool implements Callable { } try { if (wallet.isEncrypted()) { - KeyParameter aesKey = passwordToKey(true); + AesKey aesKey = passwordToKey(true); if (aesKey == null) return; // Error message already printed. key = key.encrypt(checkNotNull(wallet.getKeyCrypter()), aesKey); @@ -1177,7 +1176,7 @@ public class WalletTool implements Callable { } @Nullable - private KeyParameter passwordToKey(boolean printError) { + private AesKey passwordToKey(boolean printError) { if (password == null) { if (printError) System.err.println("You must provide a password."); @@ -1258,7 +1257,7 @@ public class WalletTool implements Callable { if (dumpPrivKeys && wallet.isEncrypted()) { if (password != null) { - final KeyParameter aesKey = passwordToKey(true); + final AesKey aesKey = passwordToKey(true); if (aesKey == null) return; // Error message already printed. printWallet( aesKey); @@ -1271,7 +1270,7 @@ public class WalletTool implements Callable { } } - private void printWallet(@Nullable KeyParameter aesKey) { + private void printWallet(@Nullable AesKey aesKey) { System.out.println(wallet.toString(dumpLookAhead, dumpPrivKeys, aesKey, true, true, chain)); }