2012-06-29 29 views
8

我在做什麼錯?我期望Java程序打印「私人」。我的目標是嘗試在Java中編寫MessageEncryptor.decrypt ruby​​方法。在Ruby中加密並在Java中解密 - 爲什麼它不起作用?

紅寶石加密(大部分代碼是從MessageEncryptor取,但不能修改元帥),但使得它更容易看到發生了什麼事情我已經提取它:

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("--") 

打印了:

tzFUIVllG2FcYD7xqGPmHQ == - UAPvdm3oN3Hog9ND9HrhEA ==

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

打印了

解密:[B @ 432a0f6c

回答

19

這是問題 - 一個問題,或者至少

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

你調用toString()一個字節數組。數組不會覆蓋toString()。如你所見,這並不會給你想要的東西。相反,你需要寫東西

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

...但你需要知道什麼編碼使用了加密前把原來的字符串轉換成字節。從Ruby代碼中我不清楚使用什麼編碼,但是如果您可以明確地使用它(理想情況下使用UTF-8),它會讓您的生活變得更加輕鬆。

簡而言之,我嫌疑人這個問題與加密無關 - 它與將文本轉換爲Ruby中的字節然後將相同的字節序列轉換回Java中的字符串有關。

當然,加密可能失敗以及但這是一個不同的問題。

+0

謝謝,喬恩。就是這樣。不能標記爲另外7分鐘的答案。 – Bradford

+0

漂亮! :-) –

相關問題