2012-10-28 45 views
9

Tôi đang vật lộn với việc di chuyển mã Java sang Golang trong vài ngày qua và bây giờ tôi đã bị kẹt. Đây là mã Java làm việc:Di chuyển mã giải mã Java sang 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); 

thực hiện của tôi trong 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) 

Những gì tôi biết cho đến nay:

  • tất cả các giá trị lỗi bỏ qua bởi _nil ở mảnh này mã
  • tiêu đề bzip2 ("BZ") phải được bỏ qua cho CBzip2InputStream, nhưng không được bỏ qua cho bzip2.NewReader
  • 16 byte đầu tiên đọc từ instream trong Java và golang đều giống nhau, bắt đầu với các byte 17 tất cả các byte khác nhau cho bất cứ lý do
+2

Nếu 16 byte đầu tiên giống nhau và phần còn lại thì không, tôi nghi ngờ hai triển khai đang sử dụng chế độ chuỗi chặn khác: http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation. Có vẻ như bạn đang sử dụng CBC ở Golang, không chắc chắn những gì mặc định là trong Java off-hand. – Gijs

+0

Tôi đã thử tất cả các phương thức có sẵn trong golang. CBC chỉ là ít nhất một vài byte đầu tiên được giải mã một cách chính xác. Có lẽ Java sử dụng ECB theo mặc định nếu không có IV được cung cấp, tôi sẽ kiểm tra trên đó, nhờ gợi ý. – fasmat

Trả lời

9

CBizp2InputStream thực sự sử dụng AES ECB. Đây là một thực hiện làm việc. Tôi bỏ qua xử lý để làm cho đoạn code ngắn hơn lỗi:

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) 

Giải thích thêm:

  • src là một io.Reader và dst là một io.Writer, cả hai cung cấp cho các chức năng giải mã như các đối số
  • keyString chứa khóa bí mật
  • tôi sử dụng i == 0 như phá vỡ tình trạng vì err có thể hoặc không thể được thiết lập để io.EOF trong đọc thành công cuối cùng (xem golang io.Reader specification)
  • 012.

Hoạt động hoàn hảo. Thực hiện mã hóa bây giờ sẽ dễ dàng.