2012-10-28 132 views
9

過去幾天我一直在努力將Java代碼遷移到Golang,現在我陷入困境。這是工作的Java代碼:將Java解密代碼遷移到Golang

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

如果前16個字節相同,其餘不相同,我懷疑這兩個實現使用不同的塊鏈接模式:http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation。看來你在Golang中使用CBC,不知道Java中的默認值是什麼。 – Gijs

+0

我嘗試了所有golang中可用的方法。 CBC是唯一至少前幾個字節被正確解密的。也許Java在默認情況下使用ECB,如果沒有IV,我會檢查一下,謝謝你的提示。 – fasmat

回答

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,二者提供給解密函數作爲參數
  • 包含KeyString中的密鑰
  • 我用i == 0作爲突破的情形,因爲err能或不能在最後的成功讀取設置爲io.EOF(見golang io.Reader specification

完美地工作。實現加密現在應該很容易。