2012-06-29 35 views
8

Tôi đang làm gì sai? Tôi dự kiến ​​chương trình Java sẽ in "riêng tư". Mục tiêu của tôi là cố gắng viết phương thức ruby ​​MessageEncryptor.decrypt trong Java.Mã hóa bằng Ruby và Giải mã trong Java - Tại sao nó không hoạt động?

mã hóa Ruby (hầu hết các mã được lấy từ MessageEncryptor, nhưng biến đổi không soái), nhưng tôi đã rút ra nó để nó dễ dàng hơn để xem những gì đang xảy ra:

require 'openssl' 
require 'active_support/base64' 

@cipher = 'aes-256-cbc' 
d = OpenSSL::Cipher.new(@cipher) 
@secret = OpenSSL::PKCS5.pbkdf2_hmac_sha1("password", "some salt", 1024, d.key_len) 
cipher = OpenSSL::Cipher::Cipher.new(@cipher) 

iv = cipher.random_iv 

cipher.encrypt 
cipher.key = @secret 
cipher.iv = iv 

encrypted_data = cipher.update("private") 
encrypted_data << cipher.final 

puts [encrypted_data, iv].map {|v| ::Base64.strict_encode64(v)}.join("--") 

nào in:

tzFUIVllG2FcYD7xqGPmHQ == - == UAPvdm3oN3Hog9ND9HrhEA đang

Java:

package decryptruby; 

import java.security.spec.KeySpec; 
import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.PBEKeySpec; 
import javax.crypto.spec.SecretKeySpec; 
import org.apache.commons.codec.binary.Base64; 

public class DecryptRuby {  
    public static String decrypt(String encrypted, String pwd, byte[] salt) 
      throws Exception { 

     String[] parts = encrypted.split("--"); 
     if (parts.length != 2) return null; 

     byte[] encryptedData = Base64.decodeBase64(parts[0]); 
     byte[] iv = Base64.decodeBase64(parts[1]); 

     SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
     KeySpec spec = new PBEKeySpec(pwd.toCharArray(), salt, 1024, 256); 
     SecretKey tmp = factory.generateSecret(spec); 
     SecretKey aesKey = new SecretKeySpec(tmp.getEncoded(), "AES"); 


     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(iv)); 

     byte[] result = cipher.doFinal(encryptedData); 
     return result.toString(); 
    } 


    public static void main(String[] args) throws Exception { 
     String encrypted = "tzFUIVllG2FcYD7xqGPmHQ==--UAPvdm3oN3Hog9ND9HrhEA=="; 

     System.out.println("Decrypted: " + decrypt(encrypted, "password", "some salt".getBytes())); 
    } 
} 

nào in

được giải: [B @ 432a0f6c

Trả lời

19

Đây là vấn đề - hoặc ít nhất là một vấn đề :

byte[] result = cipher.doFinal(encryptedData); 
return result.toString(); 

Bạn đang gọi điện thoại toString() trên một mảng byte. Mảng không ghi đè toString(). Điều đó sẽ không cho bạn những gì bạn muốn - như bạn có thể thấy. Thay vào đó, bạn cần phải viết một cái gì đó như:

return new String(result, "UTF-8"); 

... nhưng bạn cần phải biết những gì mã hóa được sử dụng để biến các chuỗi ban đầu vào byte trước khi mã hóa. Nó không rõ ràng với tôi từ mã Ruby những gì mã hóa được sử dụng, nhưng nếu bạn có thể rõ ràng về nó (lý tưởng bằng cách sử dụng UTF-8) nó sẽ làm cho cuộc sống của bạn dễ dàng hơn nhiều.

Tóm lại, tôi nghi ngờ vấn đề này không liên quan gì đến mã hóa - nó có mọi thứ cần làm với chuyển đổi văn bản thành byte trong Ruby và sau đó chuyển đổi cùng chuỗi byte trở lại thành chuỗi trong Java.

Tất nhiên mã hóa có thể bị lỗi cũng như nhưng đó là một vấn đề khác.

+0

Cảm ơn, Jon. Điều đó là vậy đó. Không thể đánh dấu là câu trả lời trong 7 phút nữa. – Bradford

+0

Rất thú vị! :-) –

Các vấn đề liên quan