Question

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
Was it helpful?

Solution

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.

OTHER TIPS

I am trying the same but usinh triple DES ECB mode. I found a code for ECB since it is not implemented in go crypto lib as it is not secure. However when initializing triple DES cipher, i am getting an error on the length of the key and i am obliged to use a certain key. The code from the cipher library throwing the error is:

// NewTripleDESCipher creates and returns a new cipher.Block.
func NewTripleDESCipher(key []byte) (cipher.Block, error) {
if len(key) != 24 {
    return nil, KeySizeError(len(key))
}

What can i do to overcome this issue? Note that in Java i dont have this problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top