2012-05-31 40 views
3

使用在https://raw.github.com/usefulfor/usefulfor/master/security/JBoss.java找到的代碼編碼的,我做了以下幾部件:河豚解密通過javax.crypto中

bash-3.2$ java -cp . JBoss -e testpython 
-27038292d345798947e2852756afcf0a 
bash-3.2$ java -cp . JBoss -d -27038292d345798947e2852756afcf0a 
testpython 

但是,我不能爲我的生命,弄清楚如何解密字符串'27038292d345798947e2852756afcf0a'在python中使用pycrypto。我的理解是,Java代碼使用Blowfish,而'jaas'是'密碼'的關鍵。但我無法理解如何在python中做到這一點。以下結果主要是不可打印的垃圾:

import Crypto 
from Crypto.Cipher import Blowfish 
from base64 import b64encode, b64decode 

bs  = Blowfish.block_size 
key  = 'jaas is the way' 
plaintext = b'27038292d345798947e2852756afcf0a' 
iv  = '\0' * 8 

c1 = Blowfish.new(key, Blowfish.MODE_ECB) 
c2 = Blowfish.new(key, Blowfish.MODE_CBC, iv) 
c3 = Blowfish.new(key, Blowfish.MODE_CFB, iv) 
c4 = Blowfish.new(key, Blowfish.MODE_OFB, iv) 

msg1 = c1.decrypt(plaintext) 
msg2 = c2.decrypt(plaintext) 
msg3 = c3.decrypt(plaintext) 
msg4 = c4.decrypt(plaintext) 

print "msg1 = %s\n" % msg1 
print "msg2 = %s\n" % msg2 
print "msg3 = %s\n" % msg3 
print "msg4 = %s\n" % msg4 

我錯過了什麼?

謝謝。

+0

歡迎SO!確保您將答案標記爲答案旁邊的複選框。 – jterrace

回答

5

首先,Java示例代碼非常糟糕。它將密文輸出爲整數,而密文應該保持爲二進制字符串。原因是整數可以用無限數量的二進制編碼表示。例如,數字1可以是'0x01'(1字節),'0x0001'(2字節)等等。在處理加密函數時,您必須對錶示非常精確。

此外,該示例使用javax.crypto API的默認值,這些值在任何地方都沒有描述。所以這真的是試驗和錯誤。

對於解決方案,您必須知道how to convert negative integers to hex strings in Python。在這種情況下,你不需要一個十六進制字符串,但它的字節表示。雖然這個概念是相同的。我使用PyCrypto的long_to_bytes將正整數(任意長度)轉換爲字節字符串。

from Crypto.Cipher import Blowfish 
from Crypto.Util.number import long_to_bytes 

def tobytestring(val, nbits): 
    """Convert an integer (val, even negative) to its byte string representation. 
    Parameter nbits is the length of the desired byte string (in bits). 
    """ 
    return long_to_bytes((val + (1 << nbits)) % (1 << nbits), nbits/8) 

key = b'jaas is the way' 
c1 = Blowfish.new(key, Blowfish.MODE_ECB) 

fromjava = b"-27038292d345798947e2852756afcf0a" 
# We don't know the real length of the ciphertext, assume it is 16 bytes 
ciphertext = tobytestring(int(fromjava, 16), 16*8) 
print c1.decrypt(ciphertext) 

輸出是:

'testpython\x06\x06\x06\x06\x06\x06' 

從你看到javax.crypto還增加了PKCS#5填充,你需要自己刪除。儘管如此,這是微不足道的。

但是,真實解決您的問題是以更好的方式做Java加密。 Python代碼將大大簡化。

+0

+1好工作搞清楚這一點。我花了一段時間試圖找出如何將負十六進制值轉換爲與BigInteger相同的字節數組。同意Java代碼是打印密文的一種可怕方法 – jterrace

+0

@jterrace如果您接受此答案,請單擊左側的大白色「V」。 – SquareRootOfTwentyThree

+0

我不是OP :)(另外,這是一個不是V的複選標記) – jterrace

0

這有助於我

private byte[] encrypt(String key, String plainText) throws GeneralSecurityException { 

    SecretKey secret_key = new SecretKeySpec(key.getBytes(), ALGORITM); 

    Cipher cipher = Cipher.getInstance(ALGORITM); 
    cipher.init(Cipher.ENCRYPT_MODE, secret_key); 

    return cipher.doFinal(plainText.getBytes()); 
} 

希望這將是對您有用,更http://dexxtr.com/post/57145943236/blowfish-encrypt-and-decrypt-in-java-android