Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migrate Java decryption code to Golang

Tags:

java

go

aes

bzip2

I'm struggling with the migration of Java code to Golang for the last few days and I am now stuck. This is the working Java code:

final Key k = new SecretKeySpec(keyString.getBytes(), "AES");
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, k);

final InputStream in = new BufferedInputStream(new FileInputStream(fileNameToDecrypt));
final CipherInputStream instream = new CipherInputStream(in, c);

if (instream.read() != 'B') {
    System.out.println("Error");
}

if (instream.read() != 'Z') {
    System.out.println("Error");
}

final CBZip2InputStream zip = new CBZip2InputStream(instream);

My implementation in Golang:

c, _ := aes.NewCipher([]byte(keyString))
// IV must be defined in golang
iv := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
d := cipher.NewCBCDecrypter(c, iv)

fi, _ := os.Open(fileNameToDecrypt)
stat, _ := fi.Stat()
enc := make([]byte, stat.Size())
dec := make([]byte, stat.Size())
fi.Read(enc)
d.CryptBlocks(dec, enc)
instream := bytes.NewBuffer(dec)
zip := bzip2.NewReader(instream)

What I know so far:

  • all error values omitted by _ are nil in this piece of code
  • the bzip2 header ("BZ") must be omitted for CBzip2InputStream, but not for bzip2.NewReader
  • the first 16 bytes read from instream in Java and golang are the same, starting with the 17th byte all bytes differ for whatever reason
like image 613
fasmat Avatar asked Oct 28 '12 11:10

fasmat


1 Answers

CBizp2InputStream indeed uses AES ECB. This is a working implementation. I omitted error handling to make the code shorter:

c, _ := aes.NewCipher([]byte(keyString))
bufIn := make([]byte, 16)
bufOut := make([]byte, 16)
dec := bytes.NewBuffer(make([]byte, 0))
var i int

for {
    i, _ = src.Read(bufIn)
    if i == 0 {
        break
    }

    c.Decrypt(bufOut, bufIn)
    dec.Write(bufOut)
}

zip := bzip2.NewReader(dec)
io.Copy(dst, zip)

Additional explanation:

  • src is an io.Reader and dst is an io.Writer, both supplied to the decrypt function as arguments
  • keyString contains the secret key
  • I use i == 0 as breaking condition because err can or cannot be set to io.EOF in the last successful read (see golang io.Reader specification)

Works perfectly. Implementing encryption should now be easy.

like image 122
fasmat Avatar answered Sep 28 '22 22:09

fasmat