Tag Archives: java

Extract private key from multibit-hd

I used this wallet for a long time. Since they dropped the development and didn’t really provide a good way to extract the private keys from the wallet, I had to find a hacky way to do it. Fortunately for me, someone else had already done this. However, I realise that this method might not be very easy for everyone, so I decided to fork the wallet and provide a patched compiled version that anyone can use to extract their keys. The instructions are the same as in the source link below.

Source for patch and instructions: https://bitcoin.stackexchange.com/questions/40507/how-can-you-extract-private-keys-from-multibit-hd/51297#51297

My patched fork: https://github.com/jra89/multibit-hd

Compiled jar: https://www.alcor.se/files/multibit-hd.jar

If you downloaded and used the compiled jar above, you can skip to step 4.

  1. Clone the MultiBit HD Git repository
  2. Apply the patch above
  3. Build the project: mvn clean dependency:sources install
  4. Start the application: java -jar mbhd-swing/target/multibit-hd.jar
  5. Go to Tools -> Sign message and enter a Bitcoin address from your wallet for which you want to recover the private key.
  6. Press finish.
  7. Read the Bitcoin address and corresponding private key from the console output

When you have the key you can import it in whatever client you have. Remember that different addresses in the wallet equals different private keys, so you will need to extract all of them via the “Sign” method in multibit-hd. If you can’t figure it out, leave a comment and I might be able to help.

Wrote an EAN13 barcode program

I decided to write a barcode generator in Java “for no apparent reason”, that can currently generator EAN13 barcodes. It’s available here in this post, but if you want the latest code then I suggest you check it out on github.

Github repo:
https://github.com/jra89/barcode

Usage:

[code]
java -jar barcode.jar numbers path barwidth barheight
[/code]

Example:

[code]
java -jar barcode.jar 999990000020 /home/user/Desktop/EAN_IMG.png 2 60
[/code]

Main.java

[code lang=”java”]
package barcode;

public class Main
{
public static void main(String[] args)
{
String code;
String path;
int barWidth;
int barHeight;

if(args.length <= 1)
{
System.out.println("Not enough parameters");
}

try
{
code = args[0];
}
catch(NullPointerException e)
{
code = "9999900000207";
}

try
{
path = args[1];
}
catch(NullPointerException e)
{
path = "/tmp/barcode.png";
}

try
{
barWidth = Integer.parseInt(args[2]);
}
catch(NullPointerException e)
{
barWidth = 1;
}

try
{
barHeight = Integer.parseInt(args[3]);
}
catch(NullPointerException e)
{
barHeight = 100;
}

Ean13 ean = new Ean13(code, path, barWidth, barHeight);
ean.createBarcodePNG();

}
}
[/code]

Ean13.java

[code lang=”java”]
package barcode;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Ean13
{
/**
* -=Structure=-
*
* Fist, First Six, Last Six
* LGR = 012
* 0 LLLLLL RRRRRR
* 1 LLGLGG RRRRRR
* 2 LLGGLG RRRRRR
* 3 LLGGGL RRRRRR
* 4 LGLLGG RRRRRR
* 5 LGGLLG RRRRRR
* 6 LGGGLL RRRRRR
* 7 LGLGLG RRRRRR
* 8 LGLGGL RRRRRR
* 9 LGGLGL RRRRRR
*
* -=Encodings=-
*
* Digit L-code G-code R-code
* 0 0001101 0100111 1110010
* 1 0011001 0110011 1100110
* 2 0010011 0011011 1101100
* 3 0111101 0100001 1000010
* 4 0100011 0011101 1011100
* 5 0110001 0111001 1001110
* 6 0101111 0000101 1010000
* 7 0111011 0010001 1000100
* 8 0110111 0001001 1001000
* 9 0001011 0010111 1110100
**/

private String code;
private String path;
private BufferedImage bi;
private Graphics2D ig2;
private int barPos;
private int barPosBin;
private int imgPixelPos;
private int barWidth;
private int barHeight;
private int imgWidth;
private int imgHeight;
private int[][] barcodeBinary;

private int[][] firstSix = {
{0,0,0,0,0,0}, //LLLLLL
{0,0,1,0,1,1}, //LLGLGG
{0,0,1,1,0,1}, //LLGGLG
{0,0,1,1,1,0}, //LLGGGL
{0,1,0,0,1,1}, //LGLLGG
{0,1,1,0,0,1}, //LGGLLG
{0,1,1,1,0,0}, //LGGGLL
{0,1,0,1,0,1}, //LGLGLG
{0,1,0,1,1,0}, //LGLGGL
{0,1,1,0,1,0} //LGGLGL
};

private int[] lastSix = {2, 2, 2, 2, 2, 2};

private int[][][] encodings = {
{
{0,0,0,1,1,0,1},
{0,1,0,0,1,1,1},
{1,1,1,0,0,1,0}
},
{
{0,0,1,1,0,0,1},
{0,1,1,0,0,1,1},
{1,1,0,0,1,1,0}
},
{
{0,0,1,0,0,1,1},
{0,0,1,1,0,1,1},
{1,1,0,1,1,0,0}
},
{
{0,1,1,1,1,0,1},
{0,1,0,0,0,0,1},
{1,0,0,0,0,1,0}
},
{
{0,1,0,0,0,1,1},
{0,0,1,1,1,0,1},
{1,0,1,1,1,0,0}
},
{
{0,1,1,0,0,0,1},
{0,1,1,1,0,0,1},
{1,0,0,1,1,1,0}
},
{
{0,1,0,1,1,1,1},
{0,0,0,0,1,0,1},
{1,0,1,0,0,0,0}
},
{
{0,1,1,1,0,1,1},
{0,0,1,0,0,0,1},
{1,0,0,0,1,0,0}
},
{
{0,1,1,0,1,1,1},
{0,0,0,1,0,0,1},
{1,0,0,1,0,0,0}
},
{
{0,0,0,1,0,1,1},
{0,0,1,0,1,1,1},
{1,1,1,0,1,0,0}
}
};

Ean13(String code, String path,int barWidth, int barHeight)
{
this.code = code;
this.path = path;
this.barPos = 12;
this.barPosBin = 7;
this.imgPixelPos = 0;
this.barcodeBinary = new int[barPos][barPosBin];
this.barWidth = barWidth;
this.barHeight = barHeight;
this.imgWidth = ((12*7) + (2*9) + (2*3) + (1*5)) * this.barWidth;
this.imgHeight = this.barHeight;
}

public void createBarcodePNG()
{
this.code += Integer.toString(calculateControlDigit(this.code));
generateBinaryMap();
generateBarcodePNG();
}

private void generateBinaryMap()
{
int first = Integer.parseInt(String.valueOf(this.code.charAt(0)));

//i = 1, first digit is not welcome to the bar
for(int i = 1; i < 13; ++i)
{
int current = Integer.parseInt(String.valueOf(this.code.charAt(i)));

if(i < 7)
this.barcodeBinary[i-1] = this.encodings[current][this.firstSix[first][i-1]];
else
this.barcodeBinary[i-1] = this.encodings[current][this.lastSix[i-7]];
}
}

private void generateBarcodePNG()
{
try {
// TYPE_INT_ARGB specifies the image format: 8-bit RGBA packed
// into integer pixels
bi = new BufferedImage(this.imgWidth, this.imgHeight, BufferedImage.TYPE_INT_ARGB);
ig2 = bi.createGraphics();

ig2.setPaint(Color.white);
ig2.fillRect ( 0, 0, bi.getWidth(), bi.getHeight() );

//Draw quiet zone
drawSpecial(0);

//Draw lead
drawSpecial(1);

//Draw first group
drawGroup(1);

//Draw separator
drawSpecial(2);

//Draw second group
drawGroup(2);

//Draw lead
drawSpecial(1);

//Draw quiet zone
drawSpecial(0);

ImageIO.write(bi, "PNG", new File(path));

} catch (IOException ie) {
ie.printStackTrace();
}
}

private void drawGroup(int groupPart)
{
int i = 0, length = 0;
if(groupPart == 1)
{
i = 0;
length = (this.barcodeBinary.length/2);
}
else if(groupPart == 2)
{
i = 6;
length = this.barcodeBinary.length;
}

for(; i < length; ++i)
{
for(int n = 0; n < this.barcodeBinary[i].length; ++n)
{
if(this.barcodeBinary[i][n] == 0)
{
ig2.setPaint(Color.white);
ig2.setStroke(new BasicStroke(this.barWidth));
}
else
{
ig2.setPaint(Color.black);
ig2.setStroke(new BasicStroke(this.barWidth));
}

int pos = this.imgPixelPos;
ig2.drawLine(pos,0,pos,this.barHeight);
this.imgPixelPos += this.barWidth;
}
}
}

private void drawSpecial(int type)
{

/*
Special Symbol Pattern
Quite Zone 000000000
Lead / Trailer 101
Separator 01010
*/

int[] quiteZone = {0,0,0,0,0,0,0,0,0};
int[] leadtrail = {1,0,1};
int[] separator = {0,1,0,1,0};
int binaryArrLength = 0;
int[] arr;

if(type == 0)
{
binaryArrLength = quiteZone.length;
arr = quiteZone;
}
else if(type == 1)
{
binaryArrLength = leadtrail.length;
arr = leadtrail;
}
else
{
binaryArrLength = separator.length;
arr = separator;
}

for(int n = 0; n < binaryArrLength; ++n)
{
if(arr[n] == 0)
ig2.setPaint(Color.white);
else
ig2.setPaint(Color.black);

int pos = this.imgPixelPos;
ig2.drawLine(pos,0,pos,this.barHeight);
this.imgPixelPos += this.barWidth;
}
}

public int calculateControlDigit(String ean)
{
int sum = 0;
for(int i = 0; i < 12; ++i)
{
int val = charToInt(ean.charAt(i));
if((i+1)%2 == 0)
sum += val*3;
else
sum += val*1;
}

return (10 – (sum % 10));
}

private int charToInt(char c)
{
return Integer.parseInt(String.valueOf(c));
}
}
[/code]

Java – 7zip unzip example

Used one of the examples in the 7zip Java bindings documentation to make this (I just modified it a little bit to actually write the unzipped data to the correct files as well, instead of just listing them). My wife needed this example so it was just something quick we threw together for a little experiment, but I thought I could put it here in case someone finds it and needs it.

Example output
[code]
Hash | Size | Filename
———-+————+———
CC27EAB9 | 199872 | oclHashcat-plus-0.14/cudaHashcat-plus32.bin
B661FF80 | 202248 | oclHashcat-plus-0.14/cudaHashcat-plus64.bin
BCFEDE0 | 224352 | oclHashcat-plus-0.14/oclHashcat-plus32.bin
39C89963 | 218472 | oclHashcat-plus-0.14/oclHashcat-plus64.bin
500CE011 | 222568 | oclHashcat-plus-0.14/vclHashcat-plus64.bin
[/code]

Code
[code lang=”java”]
package unzip;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;

import net.sf.sevenzipjbinding.ExtractOperationResult;
import net.sf.sevenzipjbinding.ISequentialOutStream;
import net.sf.sevenzipjbinding.ISevenZipInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;

public class unzip {
public static void main(String[] args) {

RandomAccessFile randomAccessFile = null;
ISevenZipInArchive inArchive = null;

try {
randomAccessFile = new RandomAccessFile("oclHashcat-plus-0.14.7z", "r");
inArchive = SevenZip.openInArchive(null, // autodetect archive type
new RandomAccessFileInStream(randomAccessFile));

// Getting simple interface of the archive inArchive
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();

System.out.println(" Hash | Size | Filename");
System.out.println("———-+————+———");

for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
final int[] hash = new int[] { 0 };
if (!item.isFolder()) {
ExtractOperationResult result;

final long[] sizeArray = new long[1];
result = item.extractSlow(new ISequentialOutStream() {
public int write(byte[] data) throws SevenZipException {

//Write to file
FileOutputStream fos;
try {
File file = new File(item.getPath());
file.getParentFile().mkdirs();
fos = new FileOutputStream(file);
fos.write(data);
fos.close();

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

hash[0] ^= Arrays.hashCode(data); // Consume data
sizeArray[0] += data.length;
return data.length; // Return amount of consumed data
}
});
if (result == ExtractOperationResult.OK) {
System.out.println(String.format("%9X | %10s | %s", //
hash[0], sizeArray[0], item.getPath()));
} else {
System.err.println("Error extracting item: " + result);
}
}
}
} catch (Exception e) {
System.err.println("Error occurs: " + e);
System.exit(1);
} finally {
if (inArchive != null) {
try {
inArchive.close();
} catch (SevenZipException e) {
System.err.println("Error closing archive: " + e);
}
}
if (randomAccessFile != null) {
try {
randomAccessFile.close();
} catch (IOException e) {
System.err.println("Error closing file: " + e);
}
}
}
}
}
[/code]