将Java解密代码迁移到Golang

时间:2012-10-28 11:51:14

标签: java go aes bzip2

过去几天我一直在努力将Java代码迁移到Golang,现在我陷入了困境。这是可用的Java代码:

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);

我在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)

到目前为止我所知道的:

  • _在此段代码中省略的所有错误值均为nil
  • CBzip2InputStream必须省略bzip2标头(“BZ”),但bzip2.NewReader
  • 不能省略
  • 在Java和golang中从instream读取的前16个字节是相同的,从第17个字节开始,所有字节因任何原因而不同

2 个答案:

答案 0 :(得分:9)

CBizp2InputStream确实使用AES ECB。这是一个有效的实施。我省略了错误处理以缩短代码:

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)

补充说明:

  • src是一个io.Reader,dst是一个io.Writer,都作为参数提供给decrypt函数
  • keyString包含密钥
  • 我使用i == 0作为中断条件,因为err在上次成功阅读中可以或不能设置为io.EOF(请参阅golang io.Reader specification

完美无缺。现在应该很容易实现加密。

答案 1 :(得分:0)

我正在尝试相同的方法,但是使用了三重DES ECB模式。我发现了ECB的代码,因为它不安全,无法在go crypto lib中实现。但是,当初始化三重DES密码时,我在密钥长度上遇到错误,我不得不使用某个密钥。密码库中引发错误的代码是:

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

我该怎么做才能克服这个问题?请注意,在Java中,我没有这个问题。