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:
_
are nil
in this piece of codeCBzip2InputStream
, but not for bzip2.NewReader
instream
in Java and golang are the same, starting with the 17th byte all bytes differ for whatever reasonCBizp2InputStream 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:
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.