【问题标题】:Migrate Java decryption code to Golang将 Java 解密代码迁移到 Golang
【发布时间】:2012-10-17 23:55:00
【问题描述】:

在过去的几天里,我一直在努力将 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 个字节开始所有字节因任何原因而不同

【问题讨论】:

  • 如果前 16 个字节相同而其余字节不同,我怀疑这两种实现使用不同的块链接模式:en.wikipedia.org/wiki/Block_cipher_modes_of_operation。看来您在 Golang 中使用 CBC,不确定 Java 中的默认值是什么。
  • 我尝试了 golang 中所有可用的方法。 CBC 是唯一至少前几个字节被正确解密的。如果没有提供 IV,Java 可能默认使用 ECB,我会检查一下,谢谢提示。

标签: java go aes bzip2


【解决方案1】:

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,两者都作为参数提供给解密函数
  • keyString 包含密钥
  • 我使用i == 0 作为中断条件,因为err 在上次成功读取时可以或不能设置为io.EOF(请参阅golang io.Reader specification

完美运行。实施加密现在应该很容易了。

【讨论】:

    【解决方案2】:

    我正在尝试相同但使用三重 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 中我没有这个问题。

    【讨论】:

    • 好吧,我将开始研究您正在使用的 Java 实现。最有可能的关键是在那里填充例如0 字节。
    猜你喜欢
    • 2014-03-06
    • 2013-05-08
    • 1970-01-01
    • 2012-10-18
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    相关资源
    最近更新 更多