/** * Create a Trezor hard wallet from a backup summary, decrypting it with a password created from * the Trezor supplied entropy */ private boolean createTrezorHardWallet() { // Get the model that contains the selected wallet backup to use SelectBackupSummaryModel selectedBackupSummaryModel = getWizardModel().getSelectBackupSummaryModel(); if (selectedBackupSummaryModel == null || selectedBackupSummaryModel.getValue() == null || selectedBackupSummaryModel.getValue().getFile() == null) { log.debug("No wallet backup to use from the model"); return false; } log.debug( "Loading hard wallet backup '" + selectedBackupSummaryModel.getValue().getFile() + "'"); try { // For Trezor hard wallets the backups are encrypted with the entropy derived password String walletPassword = null; Optional<HardwareWalletService> hardwareWalletService = CoreServices.getOrCreateHardwareWalletService(); if (hardwareWalletService.isPresent() && hardwareWalletService.get().getContext().getEntropy().isPresent()) { walletPassword = Hex.toHexString(hardwareWalletService.get().getContext().getEntropy().get()); } // Check there is a wallet password - if not then cannot decrypt backup if (walletPassword == null) { log.debug( "Cannot work out the password to decrypt the backup - there is no entropy from the Trezor"); return false; } KeyParameter backupAESKey = AESUtils.createAESKey( walletPassword.getBytes(Charsets.UTF_8), WalletManager.scryptSalt()); WalletId loadedWalletId = BackupManager.INSTANCE.loadZipBackup( selectedBackupSummaryModel.getValue().getFile(), backupAESKey); // Attempt to open the wallet final Optional<WalletSummary> walletSummaryOptional = WalletManager.INSTANCE.openWalletFromWalletId( InstallationManager.getOrCreateApplicationDataDirectory(), loadedWalletId, walletPassword); // If the wallet is present then it was opened successfully return walletSummaryOptional.isPresent(); } catch (Exception e) { log.error("Failed to restore Trezor hard wallet.", e); } // Must have failed to be here return false; }
/** * Create an wallet id from the given seed and salt * * <p>You can use this to generate a wallet id for a Trezor soft wallet passing in * WALLET_ID_SALT_USED_IN_SCRYPT_FOR_TREZOR_SOFT_WALLETS This produces a wallet id from the seed * using various trapdoor functions. The seed is typically generated from the * SeedPhraseGenerator#convertToSeed method. * * @param seed The seed to use in deriving the wallet id */ public WalletId(byte[] seed, byte[] salt) { walletId = AESUtils.generate160BitsOfEntropy(seed, salt); }
/** Create a wallet from a seed phrase and a backup summary (chosen by the user) */ private boolean createWalletFromSeedPhrase(List<String> seedPhrase) { if (!verifySeedPhrase(seedPhrase)) { return false; } // Get the model that contains the selected wallet backup to use SelectBackupSummaryModel selectedBackupSummaryModel = getWizardModel().getSelectBackupSummaryModel(); if (selectedBackupSummaryModel == null || selectedBackupSummaryModel.getValue() == null || selectedBackupSummaryModel.getValue().getFile() == null) { log.debug("No wallet backup to use from the model"); return false; } log.debug( "Loading soft wallet backup '" + selectedBackupSummaryModel.getValue().getFile() + "'"); try { WalletId loadedWalletId = BackupManager.INSTANCE.loadZipBackup( selectedBackupSummaryModel.getValue().getFile(), seedPhrase); // Locate the installation directory File applicationDataDirectory = InstallationManager.getOrCreateApplicationDataDirectory(); // Work out what the wallet credentials was from the encrypted value stored in the // WalletSummary SeedPhraseGenerator seedPhraseGenerator = new Bip39SeedPhraseGenerator(); byte[] seed = seedPhraseGenerator.convertToSeed(seedPhrase); String walletRoot = applicationDataDirectory.getAbsolutePath() + File.separator + WalletManager.createWalletRoot(loadedWalletId); WalletSummary walletSummary = WalletManager.getOrCreateWalletSummary(new File(walletRoot), loadedWalletId); KeyParameter backupAESKey = AESUtils.createAESKey(seed, WalletManager.scryptSalt()); byte[] decryptedPaddedWalletPasswordBytes = org.multibit.commons.crypto.AESUtils.decrypt( walletSummary.getEncryptedPassword(), backupAESKey, WalletManager.aesInitialisationVector()); byte[] decryptedWalletPasswordBytes = WalletManager.unpadPasswordBytes(decryptedPaddedWalletPasswordBytes); String decryptedWalletPassword = new String(decryptedWalletPasswordBytes, "UTF8"); // Attempt to open the wallet final Optional<WalletSummary> walletSummaryOptional = WalletManager.INSTANCE.openWalletFromWalletId( InstallationManager.getOrCreateApplicationDataDirectory(), loadedWalletId, decryptedWalletPassword); // If the wallet is present then it was opened successfully return walletSummaryOptional.isPresent(); } catch (Exception e) { log.error("Failed to restore wallet from seed phrase.", e); } // Must have failed to be here return false; }
/** * Create an MBHD wallet id from the given seed. This produces a wallet id from the seed using * various trapdoor functions. The seed is typically generated from the * SeedPhraseGenerator#convertToSeed method. * * @param seed The seed to use in deriving the wallet id */ public WalletId(byte[] seed) { walletId = AESUtils.generate160BitsOfEntropy(seed, WALLET_ID_SALT_USED_IN_SCRYPT_FOR_MBHD_WALLETS); }