使用在 https://raw.github.com/usefulfor/usefulfor/master/security/JBoss.java 找到的代码,我做了以下操作:
bash-3.2$ java -cp . JBoss -e testpython
-27038292d345798947e2852756afcf0a
bash-3.2$ java -cp . JBoss -d -27038292d345798947e2852756afcf0a
testpython
但是,我一辈子都无法弄清楚如何使用python中的pycrypto解密字符串" 27038292d345798947e2852756afcf0a"。 我的理解是Java代码使用Blowfish,短语"jaas is the way"作为密码的密钥。 但是我无法理解如何在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 = ' ' * 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 = %sn" % msg1
print "msg2 = %sn" % msg2
print "msg3 = %sn" % msg3
print "msg4 = %sn" % msg4
我错过了什么?
谢谢。
首先,Java示例代码非常糟糕。它将密文输出为整数,而密文应保持二进制字符串。原因是整数可以用无限数量的二进制编码表示。例如,数字 1 可以是"0x01"(1 个字节)、"0x0001"(2 个字节)等。在处理加密函数时,必须非常精确地使用表示形式。
此外,该示例使用 javax.crypto
API 的默认值,这些默认值未在任何地方进行描述。所以这真的是反复试验。
对于解决方案,您必须知道如何在 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)
输出为:
'testpythonx06x06x06x06x06x06'
从中您可以看到javax.crypto
还添加了PKCS#5填充,您需要自己删除。不过,这是微不足道的。
但是,问题的真正解决方案是以更好的方式进行Java加密。Python 代码将大大简化。
我有帮助
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