Adding compatibility with the backup files used by the web wallet

This commit is contained in:
Nelson R. Perez 2017-02-15 20:28:44 -05:00
parent 577af21b67
commit 0b0d251675
9 changed files with 464 additions and 48 deletions

View file

@ -1,8 +1,6 @@
package de.bitsharesmunich.graphenej; package de.bitsharesmunich.graphenej;
import de.bitsharesmunich.graphenej.crypto.AndroidRandomSource; import de.bitsharesmunich.graphenej.crypto.SecureRandomGenerator;
import de.bitsharesmunich.graphenej.crypto.Random;
import de.bitsharesmunich.graphenej.crypto.SecureRandomStrengthener;
import org.bitcoinj.core.DumpedPrivateKey; import org.bitcoinj.core.DumpedPrivateKey;
import org.bitcoinj.core.ECKey; import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.NetworkParameters;
@ -44,7 +42,7 @@ public class BrainKey {
String[] wordArray = words.split(","); String[] wordArray = words.split(",");
ArrayList<String> suggestedBrainKey = new ArrayList<String>(); ArrayList<String> suggestedBrainKey = new ArrayList<String>();
assert (wordArray.length == DICT_WORD_COUNT); assert (wordArray.length == DICT_WORD_COUNT);
SecureRandom secureRandom = Random.getSecureRandom(); SecureRandom secureRandom = SecureRandomGenerator.getSecureRandom();
int index; int index;
for (int i = 0; i < BRAINKEY_WORD_COUNT; i++) { for (int i = 0; i < BRAINKEY_WORD_COUNT; i++) {
index = secureRandom.nextInt(DICT_WORD_COUNT - 1); index = secureRandom.nextInt(DICT_WORD_COUNT - 1);

View file

@ -1,28 +1,112 @@
package de.bitsharesmunich.graphenej; package de.bitsharesmunich.graphenej;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import de.bitsharesmunich.graphenej.crypto.SecureRandomStrengthener; import de.bitsharesmunich.graphenej.crypto.SecureRandomStrengthener;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import de.bitsharesmunich.graphenej.models.backup.WalletBackup;
import org.bitcoinj.core.ECKey; import org.bitcoinj.core.ECKey;
/** /**
* Class to manage the Bin Files * Class to manage the backup files
* *
* @author Henry Varona * @author Henry Varona
* @author Nelson R. Pérez
*/ */
public abstract class FileBin { public abstract class FileBin {
public static final int PUBLIC_KEY_LENGTH = 33;
/**
* Method that receives as input both the bytes from the bin backup and the string used to encrypt the
* data contained in it.
*
* The procedure of deserializing the wallet backup involves first decrypting the data and then decompressing
* it using the LZMA algorithm. Once this two steps are performed, the resulting byte sequence represents
* a JSON-formatted object with one or more wallet and private keys information.
*
* @param input: Input bytes
* @param password: Password used to derive the encryption key
* @return: An instance of the WalletBackup class.
*/
public static WalletBackup deserializeWalletBackup(byte[] input, String password){
try{
byte[] publicKey = new byte[PUBLIC_KEY_LENGTH];
byte[] rawDataEncripted = new byte[input.length - PUBLIC_KEY_LENGTH];
System.arraycopy(input, 0, publicKey, 0, PUBLIC_KEY_LENGTH);
System.arraycopy(input, PUBLIC_KEY_LENGTH, rawDataEncripted, 0, rawDataEncripted.length);
MessageDigest md = MessageDigest.getInstance("SHA-256");
ECKey randomECKey = ECKey.fromPublicOnly(publicKey);
byte[] finalKey = randomECKey.getPubKeyPoint().multiply(ECKey.fromPrivate(md.digest(password.getBytes("UTF-8"))).getPrivKey()).normalize().getXCoord().getEncoded();
MessageDigest md1 = MessageDigest.getInstance("SHA-512");
finalKey = md1.digest(finalKey);
byte[] decryptedData = Util.decryptAES(rawDataEncripted, Util.bytesToHex(finalKey).getBytes());
byte[] checksum = new byte[4];
System.arraycopy(decryptedData, 0, checksum, 0, 4);
byte[] compressedData = new byte[decryptedData.length - 4];
System.arraycopy(decryptedData, 4, compressedData, 0, compressedData.length);
byte[] decompressedData = Util.decompress(compressedData, Util.LZMA);
String walletString = new String(decompressedData, "UTF-8");
System.out.println("Wallet str: "+walletString);
return new GsonBuilder().create().fromJson(walletString, WalletBackup.class);
}catch(NoSuchAlgorithmException e){
System.out.println("NoSuchAlgorithmException. Msg: "+e.getMessage());
} catch (UnsupportedEncodingException e) {
System.out.println("UnsupportedEncodingException. Msg: "+e.getMessage());
}
return null;
}
public static byte[] serializeWalletBackup(WalletBackup walletBackup, String password){
SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance();
//randomStrengthener.addEntropySource(new AndroidRandomSource());
SecureRandom secureRandom = randomStrengthener.generateAndSeedRandomNumberGenerator();
try{
String json = new GsonBuilder().create().toJson(walletBackup, WalletBackup.class);
byte[] compressed = Util.compress(json.getBytes(), Util.LZMA);
System.out.println("json: "+json);
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] checksum = md.digest(compressed);
byte[] checksummed = new byte[compressed.length + 4];
System.arraycopy(checksum, 0, checksummed, 0, 4);
System.arraycopy(compressed, 0, checksummed, 4, compressed.length);
byte[] randomKey = new byte[32];
secureRandom.nextBytes(randomKey);
ECKey randomECKey = ECKey.fromPrivate(md.digest(randomKey));
byte[] randPubKey = randomECKey.getPubKey();
byte[] finalKey = randomECKey.getPubKeyPoint().multiply(ECKey.fromPrivate(md.digest(password.getBytes("UTF-8"))).getPrivKey()).normalize().getXCoord().getEncoded();
MessageDigest md1 = MessageDigest.getInstance("SHA-512");
finalKey = md1.digest(finalKey);
checksummed = Util.encryptAES(checksummed, Util.byteToString(finalKey).getBytes());
byte[] finalPayload = new byte[checksummed.length + randPubKey.length];
System.arraycopy(randPubKey, 0, finalPayload, 0, randPubKey.length);
System.arraycopy(checksummed, 0, finalPayload, randPubKey.length, checksummed.length);
return finalPayload;
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException. Msg: "+e.getMessage());
} catch (UnsupportedEncodingException e) {
System.out.println("UnsupportedEncodingException. Msg: "+e.getMessage());
}
return null;
}
/** /**
* Method to get the brainkey fron an input of bytes * Method to get the brainkey fron an input of bytes
* *
@ -30,7 +114,11 @@ public abstract class FileBin {
* @param password the pin code * @param password the pin code
* @return the brainkey file, or null if the file or the password are * @return the brainkey file, or null if the file or the password are
* incorrect * incorrect
*
* @deprecated use {@link #deserializeWalletBackup(byte[], String)} instead, as it is a more complete method
* that will return a WalletBackup class instance.
*/ */
@Deprecated
public static String getBrainkeyFromByte(byte[] input, String password) { public static String getBrainkeyFromByte(byte[] input, String password) {
try { try {
byte[] publicKey = new byte[33]; byte[] publicKey = new byte[33];
@ -47,27 +135,12 @@ public abstract class FileBin {
finalKey = md1.digest(finalKey); finalKey = md1.digest(finalKey);
byte[] rawData = Util.decryptAES(rawDataEncripted, Util.byteToString(finalKey).getBytes()); byte[] rawData = Util.decryptAES(rawDataEncripted, Util.byteToString(finalKey).getBytes());
try {
FileOutputStream out = new FileOutputStream("/Users/nelson/Development/Java/Fullerene/src/main/java/de/bitsharesmunich/graphenej/decrypted.bin");
out.write(rawData);
out.close();
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException. Msg: "+e.getMessage());
} catch (IOException e) {
System.out.println("IOException. Msg: "+e.getMessage());
}
byte[] checksum = new byte[4]; byte[] checksum = new byte[4];
System.arraycopy(rawData, 0, checksum, 0, 4); System.arraycopy(rawData, 0, checksum, 0, 4);
byte[] compressedData = new byte[rawData.length - 4]; byte[] compressedData = new byte[rawData.length - 4];
System.arraycopy(rawData, 4, compressedData, 0, compressedData.length); System.arraycopy(rawData, 4, compressedData, 0, compressedData.length);
System.out.println("raw: "+Util.bytesToHex(rawData)); byte[] wallet_object_bytes = Util.decompress(compressedData, Util.XZ);
System.out.println("checksum: "+Util.bytesToHex(checksum));
System.out.println("compressed: "+Util.bytesToHex(compressedData));
byte[] wallet_object_bytes = Util.decompress(rawData, Util.LZMA);
String wallet_string = new String(wallet_object_bytes, "UTF-8"); String wallet_string = new String(wallet_object_bytes, "UTF-8");
JsonObject wallet = new JsonParser().parse(wallet_string).getAsJsonObject(); JsonObject wallet = new JsonParser().parse(wallet_string).getAsJsonObject();
if (wallet.get("wallet").isJsonArray()) { if (wallet.get("wallet").isJsonArray()) {
@ -106,7 +179,10 @@ public abstract class FileBin {
* @param password The pin code * @param password The pin code
* @param accountName The Account Name * @param accountName The Account Name
* @return The array byte of the file, or null if an error happens * @return The array byte of the file, or null if an error happens
*
* @deprecated use {@link #serializeWalletBackup(WalletBackup, String)} instead.
*/ */
@Deprecated
public static byte[] getBytesFromBrainKey(String BrainKey, String password, String accountName) { public static byte[] getBytesFromBrainKey(String BrainKey, String password, String accountName) {
try { try {
@ -157,6 +233,4 @@ public abstract class FileBin {
} }
return null; return null;
} }
} }

View file

@ -33,7 +33,6 @@ public class Transaction implements ByteSerializable, JsonSerializable {
public static final String KEY_EXTENSIONS = "extensions"; public static final String KEY_EXTENSIONS = "extensions";
public static final String KEY_REF_BLOCK_NUM = "ref_block_num"; public static final String KEY_REF_BLOCK_NUM = "ref_block_num";
public static final String KEY_REF_BLOCK_PREFIX = "ref_block_prefix"; public static final String KEY_REF_BLOCK_PREFIX = "ref_block_prefix";
public static final String TIME_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
private ECKey privateKey; private ECKey privateKey;
private BlockData blockData; private BlockData blockData;
@ -205,7 +204,7 @@ public class Transaction implements ByteSerializable, JsonSerializable {
// Formatting expiration time // Formatting expiration time
Date expirationTime = new Date(blockData.getExpiration() * 1000); Date expirationTime = new Date(blockData.getExpiration() * 1000);
SimpleDateFormat dateFormat = new SimpleDateFormat(TIME_DATE_FORMAT); SimpleDateFormat dateFormat = new SimpleDateFormat(Util.TIME_DATE_FORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
// Adding expiration // Adding expiration
@ -260,7 +259,7 @@ public class Transaction implements ByteSerializable, JsonSerializable {
int refBlockNum = jsonObject.get(KEY_REF_BLOCK_NUM).getAsInt(); int refBlockNum = jsonObject.get(KEY_REF_BLOCK_NUM).getAsInt();
long refBlockPrefix = jsonObject.get(KEY_REF_BLOCK_PREFIX).getAsLong(); long refBlockPrefix = jsonObject.get(KEY_REF_BLOCK_PREFIX).getAsLong();
String expiration = jsonObject.get(KEY_EXPIRATION).getAsString(); String expiration = jsonObject.get(KEY_EXPIRATION).getAsString();
SimpleDateFormat dateFormat = new SimpleDateFormat(TIME_DATE_FORMAT); SimpleDateFormat dateFormat = new SimpleDateFormat(Util.TIME_DATE_FORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
Date expirationDate = dateFormat.parse(expiration, new ParsePosition(0)); Date expirationDate = dateFormat.parse(expiration, new ParsePosition(0));
BlockData blockData = new BlockData(refBlockNum, refBlockPrefix, expirationDate.getTime()); BlockData blockData = new BlockData(refBlockNum, refBlockPrefix, expirationDate.getTime());

View file

@ -1,11 +1,8 @@
package de.bitsharesmunich.graphenej; package de.bitsharesmunich.graphenej;
import org.tukaani.xz.FinishableOutputStream; import com.google.common.primitives.Bytes;
import org.tukaani.xz.LZMA2Options; import org.tukaani.xz.*;
import org.tukaani.xz.LZMAInputStream;
import org.tukaani.xz.LZMAOutputStream;
import org.tukaani.xz.XZInputStream;
import org.tukaani.xz.XZOutputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -33,6 +30,17 @@ public class Util {
public static final int LZMA = 0; public static final int LZMA = 0;
public static final int XZ = 1; public static final int XZ = 1;
/**
* AES encryption key length in bytes
*/
public static final int KEY_LENGTH = 32;
/**
* Time format used across the platform
*/
public static final String TIME_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
/** /**
* Converts an hexadecimal string to its corresponding byte[] value. * Converts an hexadecimal string to its corresponding byte[] value.
* @param s: String with hexadecimal numbers representing a byte array. * @param s: String with hexadecimal numbers representing a byte array.
@ -94,10 +102,10 @@ public class Util {
}else if(which == Util.XZ){ }else if(which == Util.XZ){
out = new XZOutputStream(output, options); out = new XZOutputStream(output, options);
} }
byte[] buf = new byte[inputBytes.length]; byte[] inputBuffer = new byte[inputBytes.length];
int size; int size;
while ((size = input.read(buf)) != -1) { while ((size = input.read(inputBuffer)) != -1) {
out.write(buf, 0, size); out.write(inputBuffer, 0, size);
} }
out.finish(); out.finish();
return output.toByteArray(); return output.toByteArray();
@ -124,27 +132,51 @@ public class Util {
public static byte[] decompress(byte[] inputBytes, int which) { public static byte[] decompress(byte[] inputBytes, int which) {
InputStream in = null; InputStream in = null;
try { try {
System.out.println("Bytes: "+Util.bytesToHex(inputBytes));
ByteArrayInputStream input = new ByteArrayInputStream(inputBytes); ByteArrayInputStream input = new ByteArrayInputStream(inputBytes);
ByteArrayOutputStream output = new ByteArrayOutputStream(2048); ByteArrayOutputStream output = new ByteArrayOutputStream(16*2048);
if(which == XZ) { if(which == XZ) {
in = new XZInputStream(input); in = new XZInputStream(input);
}else if(which == LZMA){ }else if(which == LZMA){
in = new LZMAInputStream(input); in = new LZMAInputStream(input);
} }
int size; int size;
while ((size = in.read()) != -1) { try{
output.write(size); while ((size = in.read()) != -1) {
output.write(size);
}
}catch(CorruptedInputException e){
// Taking property byte
byte[] properties = Arrays.copyOfRange(inputBytes, 0, 1);
// Taking dict size bytes
byte[] dictSize = Arrays.copyOfRange(inputBytes, 1, 5);
// Taking uncompressed size bytes
byte[] uncompressedSize = Arrays.copyOfRange(inputBytes, 5, 13);
// Reversing bytes in header
byte[] header = Bytes.concat(properties, Util.revertBytes(dictSize), Util.revertBytes(uncompressedSize));
byte[] payload = Arrays.copyOfRange(inputBytes, 13, inputBytes.length);
// Trying again
input = new ByteArrayInputStream(Bytes.concat(header, payload));
output = new ByteArrayOutputStream(2048);
if(which == XZ) {
in = new XZInputStream(input);
}else if(which == LZMA){
in = new LZMAInputStream(input);
}
try{
while ((size = in.read()) != -1) {
output.write(size);
}
}catch(CorruptedInputException ex){
System.out.println("CorruptedInputException. Msg: "+ex.getMessage());
}
} }
in.close(); in.close();
return output.toByteArray(); return output.toByteArray();
} catch (IOException ex) { } catch (IOException ex) {
Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
} finally {
// try {
// in.close();
// } catch (IOException ex) {
// Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
// }
} }
return null; return null;
} }
@ -178,6 +210,14 @@ public class Util {
return ByteBuffer.allocate(Long.SIZE / 8).putLong(Long.reverseBytes(input)).array(); return ByteBuffer.allocate(Long.SIZE / 8).putLong(Long.reverseBytes(input)).array();
} }
public static byte[] revertBytes(byte[] array){
byte[] reverted = new byte[array.length];
for(int i = 0; i < reverted.length; i++){
reverted[i] = array[array.length - i - 1];
}
return reverted;
}
/** /**
* Function to encrypt a message with AES * Function to encrypt a message with AES
* @param input data to encrypt * @param input data to encrypt

View file

@ -5,7 +5,7 @@ import java.security.SecureRandom;
/** /**
* Created by nelson on 12/20/16. * Created by nelson on 12/20/16.
*/ */
public class Random { public class SecureRandomGenerator {
public static SecureRandom getSecureRandom(){ public static SecureRandom getSecureRandom(){
SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance(); SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance();

View file

@ -0,0 +1,31 @@
package de.bitsharesmunich.graphenej.models.backup;
/**
* Class used to represent an entry in the "linked_accounts" field of the JSON-formatted backup file.
* Created by nelson on 2/15/17.
*/
public class LinkedAccount {
private String name;
private String chainId;
public LinkedAccount(String name, String chainId){
this.name = name;
this.chainId = chainId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getChainId() {
return chainId;
}
public void setChainId(String chainId) {
this.chainId = chainId;
}
}

View file

@ -0,0 +1,38 @@
package de.bitsharesmunich.graphenej.models.backup;
import de.bitsharesmunich.graphenej.Address;
import de.bitsharesmunich.graphenej.Util;
import org.bitcoinj.core.ECKey;
/**
* Class used to represent an entry in the "private_keys" array field in the JSON-formatted
* backup file.
*
* Created by nelson on 2/14/17.
*/
public class PrivateKeyBackup {
public String encrypted_key;
public String pubkey;
public int brainkey_sequence;
public int id;
public PrivateKeyBackup(byte[] privateKey, int brainkeySequence, int id, byte[] encryptionKey){
this.encrypted_key = encryptPrivateKey(privateKey, encryptionKey);
this.brainkey_sequence = brainkeySequence;
this.id = id;
deriveAddress(privateKey);
}
public byte[] decryptPrivateKey(byte[] encryptionKey){
return Util.decryptAES(Util.hexToBytes(encrypted_key), encryptionKey);
}
public String encryptPrivateKey(byte[] data, byte[] encryptionKey){
return Util.bytesToHex(Util.encryptAES(data, encryptionKey));
}
private void deriveAddress(byte[] privateKey){
Address address = new Address(ECKey.fromPublicOnly(ECKey.fromPrivate(privateKey).getPubKey()));
this.pubkey = address.toString();
}
}

View file

@ -0,0 +1,187 @@
package de.bitsharesmunich.graphenej.models.backup;
import de.bitsharesmunich.graphenej.Chains;
import de.bitsharesmunich.graphenej.Util;
import de.bitsharesmunich.graphenej.crypto.SecureRandomGenerator;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* This class holds data deserialized from a wallet in the backup file.
*
* Created by nelson on 2/14/17.
*/
public class Wallet {
private String public_name;
private String password_pubkey;
private String encryption_key;
private String encrypted_brainkey;
private String brainkey_pubkey;
private int brainkey_sequence;
private String brainkey_backup_date;
private String created;
private String last_modified;
private String chain_id;
private String id;
private String backup_date;
/**
* No args constructor
*/
public Wallet(){}
public Wallet(String name){
this.public_name = name;
this.id = name;
}
/**
* Wallet constructor that takes a few arguments.
* @param name: The name of this wallet.
* @param brainKey: The brain key to be used.
* @param brainkeySequence: The brain key sequence.
* @param chainId: The chain id
* @param password: Password used to encrypt all sensitive data.
*/
public Wallet(String name, String brainKey, int brainkeySequence, String chainId, String password){
this(name);
SecureRandom secureRandom = SecureRandomGenerator.getSecureRandom();
byte[] decryptedKey = new byte[Util.KEY_LENGTH];
secureRandom.nextBytes(decryptedKey);
this.encryption_key = Util.bytesToHex(Util.encryptAES(decryptedKey, password.getBytes()));
this.encrypted_brainkey = Util.bytesToHex(Util.encryptAES(decryptedKey, brainKey.getBytes()));
this.brainkey_sequence = brainkeySequence;
this.chain_id = chainId;
//TODO: Find out how to fill "password_pubkey" and "brainkey_pubkey" fields.
Date now = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat(Util.TIME_DATE_FORMAT);
this.created = dateFormat.format(now);
this.last_modified = created;
this.backup_date = created;
this.brainkey_backup_date = created;
}
/**
* Method that will return the decrypted version of the "encrypted_brainkey" field.
* @param password: Password used to encrypt the encryption key.
* @return: The brainkey in its plaintext version.
*/
public String decryptBrainKey(String password){
byte[] decryptedKey = getEncryptionKey(password);
byte[] encryptedBrainKey = Util.hexToBytes(encrypted_brainkey);
return new String(Util.decryptAES(encryptedBrainKey, decryptedKey));
}
/**
* Decrypts the encryption key, which is also provided in an encrypted form.
* @param password: The password used to encrypt the encryption key.
* @return: The encryption key.
*/
public byte[] getEncryptionKey(String password){
return Util.decryptAES(Util.hexToBytes(encryption_key), password.getBytes());
}
public String getPrivateName() {
return public_name;
}
public void setPrivateName(String privateName) {
this.public_name = privateName;
}
public String getPasswordPubkey() {
return password_pubkey;
}
public void setPasswordPubkey(String password_pubkey) {
this.password_pubkey = password_pubkey;
}
/**
* Gets the cyphertext version of the encryption key.
* @return: Encryption key in its cyphertext version.
*/
public String getEncryptionKey() {
return encryption_key;
}
public void setEncryptionKey(String encryption_key) {
this.encryption_key = encryption_key;
}
public String getEncryptedBrainkey() {
return encrypted_brainkey;
}
public void setEncryptedBrainkey(String encrypted_brainkey) {
this.encrypted_brainkey = encrypted_brainkey;
}
public String getBrainkeyPubkey() {
return brainkey_pubkey;
}
public void setBrainkeyPubkey(String brainkey_pubkey) {
this.brainkey_pubkey = brainkey_pubkey;
}
public int getBrainkeySequence() {
return brainkey_sequence;
}
public void setBrainkeySequence(int brainkey_sequence) {
this.brainkey_sequence = brainkey_sequence;
}
public String getBrainkeyBackup_date() {
return brainkey_backup_date;
}
public void setBrainkeyBackupDate(String brainkey_backup_date) {
this.brainkey_backup_date = brainkey_backup_date;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getLastModified() {
return last_modified;
}
public void setLastModified(String last_modified) {
this.last_modified = last_modified;
}
public String getChainId() {
return chain_id;
}
public void setChainId(String chain_id) {
this.chain_id = chain_id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getBackupDate() {
return backup_date;
}
public void setBackupDate(String backup_date) {
this.backup_date = backup_date;
}
}

View file

@ -0,0 +1,49 @@
package de.bitsharesmunich.graphenej.models.backup;
import java.util.List;
/**
* This class is used to represent the JSON-formatted version of the file backup containing one or more
* wallets and keys.
*
* Created by nelson on 2/14/17.
*/
public class WalletBackup {
private Wallet[] wallet;
private PrivateKeyBackup[] private_keys;
private LinkedAccount[] linked_accounts;
public WalletBackup(List<Wallet> wallets, List<PrivateKeyBackup> privateKeys, List<LinkedAccount> linkedAccounts){
this.wallet = wallets.toArray(new Wallet[wallets.size()]);
this.private_keys = privateKeys.toArray(new PrivateKeyBackup[privateKeys.size()]);
this.linked_accounts = linkedAccounts.toArray(new LinkedAccount[linkedAccounts.size()]);
}
public Wallet[] getWallets(){
return wallet;
}
public PrivateKeyBackup[] getPrivateKeys(){
return private_keys;
}
public LinkedAccount[] getLinkedAccounts(){
return linked_accounts;
}
public Wallet getWallet(int index){
return wallet[index];
}
public PrivateKeyBackup getPrivateKeyBackup(int index){
return private_keys[index];
}
public int getWalletCount(){
return wallet.length;
}
public int getKeyCount(){
return private_keys.length;
}
}