Adding compatibility with the backup files used by the web wallet
This commit is contained in:
parent
577af21b67
commit
0b0d251675
9 changed files with 464 additions and 48 deletions
|
@ -1,8 +1,6 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
import de.bitsharesmunich.graphenej.crypto.AndroidRandomSource;
|
||||
import de.bitsharesmunich.graphenej.crypto.Random;
|
||||
import de.bitsharesmunich.graphenej.crypto.SecureRandomStrengthener;
|
||||
import de.bitsharesmunich.graphenej.crypto.SecureRandomGenerator;
|
||||
import org.bitcoinj.core.DumpedPrivateKey;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
|
@ -44,7 +42,7 @@ public class BrainKey {
|
|||
String[] wordArray = words.split(",");
|
||||
ArrayList<String> suggestedBrainKey = new ArrayList<String>();
|
||||
assert (wordArray.length == DICT_WORD_COUNT);
|
||||
SecureRandom secureRandom = Random.getSecureRandom();
|
||||
SecureRandom secureRandom = SecureRandomGenerator.getSecureRandom();
|
||||
int index;
|
||||
for (int i = 0; i < BRAINKEY_WORD_COUNT; i++) {
|
||||
index = secureRandom.nextInt(DICT_WORD_COUNT - 1);
|
||||
|
|
|
@ -1,28 +1,112 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import de.bitsharesmunich.graphenej.crypto.SecureRandomStrengthener;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import de.bitsharesmunich.graphenej.models.backup.WalletBackup;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
|
||||
/**
|
||||
* Class to manage the Bin Files
|
||||
* Class to manage the backup files
|
||||
*
|
||||
* @author Henry Varona
|
||||
* @author Nelson R. Pérez
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
@ -30,7 +114,11 @@ public abstract class FileBin {
|
|||
* @param password the pin code
|
||||
* @return the brainkey file, or null if the file or the password are
|
||||
* 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) {
|
||||
try {
|
||||
byte[] publicKey = new byte[33];
|
||||
|
@ -47,27 +135,12 @@ public abstract class FileBin {
|
|||
finalKey = md1.digest(finalKey);
|
||||
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];
|
||||
System.arraycopy(rawData, 0, checksum, 0, 4);
|
||||
byte[] compressedData = new byte[rawData.length - 4];
|
||||
System.arraycopy(rawData, 4, compressedData, 0, compressedData.length);
|
||||
|
||||
System.out.println("raw: "+Util.bytesToHex(rawData));
|
||||
System.out.println("checksum: "+Util.bytesToHex(checksum));
|
||||
System.out.println("compressed: "+Util.bytesToHex(compressedData));
|
||||
|
||||
byte[] wallet_object_bytes = Util.decompress(rawData, Util.LZMA);
|
||||
byte[] wallet_object_bytes = Util.decompress(compressedData, Util.XZ);
|
||||
String wallet_string = new String(wallet_object_bytes, "UTF-8");
|
||||
JsonObject wallet = new JsonParser().parse(wallet_string).getAsJsonObject();
|
||||
if (wallet.get("wallet").isJsonArray()) {
|
||||
|
@ -106,7 +179,10 @@ public abstract class FileBin {
|
|||
* @param password The pin code
|
||||
* @param accountName The Account Name
|
||||
* @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) {
|
||||
|
||||
try {
|
||||
|
@ -157,6 +233,4 @@ public abstract class FileBin {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ public class Transaction implements ByteSerializable, JsonSerializable {
|
|||
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_PREFIX = "ref_block_prefix";
|
||||
public static final String TIME_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
|
||||
|
||||
private ECKey privateKey;
|
||||
private BlockData blockData;
|
||||
|
@ -205,7 +204,7 @@ public class Transaction implements ByteSerializable, JsonSerializable {
|
|||
|
||||
// Formatting expiration time
|
||||
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"));
|
||||
|
||||
// Adding expiration
|
||||
|
@ -260,7 +259,7 @@ public class Transaction implements ByteSerializable, JsonSerializable {
|
|||
int refBlockNum = jsonObject.get(KEY_REF_BLOCK_NUM).getAsInt();
|
||||
long refBlockPrefix = jsonObject.get(KEY_REF_BLOCK_PREFIX).getAsLong();
|
||||
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"));
|
||||
Date expirationDate = dateFormat.parse(expiration, new ParsePosition(0));
|
||||
BlockData blockData = new BlockData(refBlockNum, refBlockPrefix, expirationDate.getTime());
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
package de.bitsharesmunich.graphenej;
|
||||
|
||||
import org.tukaani.xz.FinishableOutputStream;
|
||||
import org.tukaani.xz.LZMA2Options;
|
||||
import org.tukaani.xz.LZMAInputStream;
|
||||
import org.tukaani.xz.LZMAOutputStream;
|
||||
import org.tukaani.xz.XZInputStream;
|
||||
import org.tukaani.xz.XZOutputStream;
|
||||
import com.google.common.primitives.Bytes;
|
||||
import org.tukaani.xz.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -33,6 +30,17 @@ public class Util {
|
|||
public static final int LZMA = 0;
|
||||
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.
|
||||
* @param s: String with hexadecimal numbers representing a byte array.
|
||||
|
@ -94,10 +102,10 @@ public class Util {
|
|||
}else if(which == Util.XZ){
|
||||
out = new XZOutputStream(output, options);
|
||||
}
|
||||
byte[] buf = new byte[inputBytes.length];
|
||||
byte[] inputBuffer = new byte[inputBytes.length];
|
||||
int size;
|
||||
while ((size = input.read(buf)) != -1) {
|
||||
out.write(buf, 0, size);
|
||||
while ((size = input.read(inputBuffer)) != -1) {
|
||||
out.write(inputBuffer, 0, size);
|
||||
}
|
||||
out.finish();
|
||||
return output.toByteArray();
|
||||
|
@ -124,27 +132,51 @@ public class Util {
|
|||
public static byte[] decompress(byte[] inputBytes, int which) {
|
||||
InputStream in = null;
|
||||
try {
|
||||
System.out.println("Bytes: "+Util.bytesToHex(inputBytes));
|
||||
ByteArrayInputStream input = new ByteArrayInputStream(inputBytes);
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream(2048);
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream(16*2048);
|
||||
if(which == XZ) {
|
||||
in = new XZInputStream(input);
|
||||
}else if(which == LZMA){
|
||||
in = new LZMAInputStream(input);
|
||||
}
|
||||
int size;
|
||||
while ((size = in.read()) != -1) {
|
||||
output.write(size);
|
||||
try{
|
||||
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();
|
||||
return output.toByteArray();
|
||||
} catch (IOException 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;
|
||||
}
|
||||
|
@ -178,6 +210,14 @@ public class Util {
|
|||
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
|
||||
* @param input data to encrypt
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.security.SecureRandom;
|
|||
/**
|
||||
* Created by nelson on 12/20/16.
|
||||
*/
|
||||
public class Random {
|
||||
public class SecureRandomGenerator {
|
||||
|
||||
public static SecureRandom getSecureRandom(){
|
||||
SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance();
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue