java 和 Python Blowfish 的实施产生不同的结果
java and Python implementation of Blowfish produce different results
我在 java 中有一个遗留的河豚实现,我正试图将其移植到 Python。
Java:
import blowfishj.*;
import org.apache.commons.codec.binary.Hex;
private static byte[] EncryptBlowFish(byte[] sStr, String sSecret) {
byte[] key = sSecret.getBytes();
byte[] cipher = new byte[sStr.length];
BlowfishECB blowfish = new BlowfishECB(key, 0, key.length);
blowfish.encrypt(sStr, 0, cipher, 0, sStr.length);
return (new String(Hex.encodeHex(cipher)));
}
Python:
from Crypto.Cipher import Blowfish
import binascii
def encrypt(encr_str, key_str):
cipher = Blowfish.new(key_str, Blowfish.MODE_ECB)
return binascii.hexlify(cipher.encrypt(encr_str)).decode('utf-8')
如果要加密的字符串是“12345678”,密钥是“1234567890123456”,java代码输出"e00723bbb58234aa",python代码输出“61d2570dc6e09632”。
由于 java 代码是遗留的,我不能碰它。 This indicates there's a problem in pycrypto's implementation of blowfish. However, I can confirm the accepted answer here works. Not sure why though. I tried both pycrypto as well as this blowfish module 结果相同。
关于如何在 Python 中复制与遗留 java 代码相同的河豚输出的任何想法?
感谢@Kai Iskratsch 指出了正确的方向。
参考:
What's the difference between Blowfish and Blowfish-compat?
这是对我有用的代码。
Python:
from Crypto.Cipher import Blowfish
from binascii import hexlify
def encrypt(key, string):
"""
Encrypts input string using BlowFish-Compat ECB algorithm.
:param key: secret key
:param string: string to encrypt
:return: encrypted string
"""
cipher = Blowfish.new(key, Blowfish.MODE_ECB)
return hexlify(_reverse_bytes(cipher.encrypt(_reverse_bytes(string)))).decode('utf-8')
@staticmethod
def _reverse_bytes(data):
"""
Takes data and reverses byte order to fit blowfish-compat format. For example, using _reverse_bytes('12345678')
will return 43218765.
:param data as bytes
:return: reversed bytes
"""
data_size = 0
for n in data:
data_size += 1
reversed_bytes = bytearray()
i = 0
for x in range(0, data_size // 4):
a = (data[i:i + 4])
i += 4
z = 0
n0 = a[z]
n1 = a[z + 1]
n2 = a[z + 2]
n3 = a[z + 3]
reversed_bytes.append(n3)
reversed_bytes.append(n2)
reversed_bytes.append(n1)
reversed_bytes.append(n0)
return bytes(reversed_bytes)
我在 java 中有一个遗留的河豚实现,我正试图将其移植到 Python。
Java:
import blowfishj.*;
import org.apache.commons.codec.binary.Hex;
private static byte[] EncryptBlowFish(byte[] sStr, String sSecret) {
byte[] key = sSecret.getBytes();
byte[] cipher = new byte[sStr.length];
BlowfishECB blowfish = new BlowfishECB(key, 0, key.length);
blowfish.encrypt(sStr, 0, cipher, 0, sStr.length);
return (new String(Hex.encodeHex(cipher)));
}
Python:
from Crypto.Cipher import Blowfish
import binascii
def encrypt(encr_str, key_str):
cipher = Blowfish.new(key_str, Blowfish.MODE_ECB)
return binascii.hexlify(cipher.encrypt(encr_str)).decode('utf-8')
如果要加密的字符串是“12345678”,密钥是“1234567890123456”,java代码输出"e00723bbb58234aa",python代码输出“61d2570dc6e09632”。
由于 java 代码是遗留的,我不能碰它。 This indicates there's a problem in pycrypto's implementation of blowfish. However, I can confirm the accepted answer here works. Not sure why though. I tried both pycrypto as well as this blowfish module 结果相同。
关于如何在 Python 中复制与遗留 java 代码相同的河豚输出的任何想法?
感谢@Kai Iskratsch 指出了正确的方向。
参考:
What's the difference between Blowfish and Blowfish-compat?
这是对我有用的代码。
Python:
from Crypto.Cipher import Blowfish
from binascii import hexlify
def encrypt(key, string):
"""
Encrypts input string using BlowFish-Compat ECB algorithm.
:param key: secret key
:param string: string to encrypt
:return: encrypted string
"""
cipher = Blowfish.new(key, Blowfish.MODE_ECB)
return hexlify(_reverse_bytes(cipher.encrypt(_reverse_bytes(string)))).decode('utf-8')
@staticmethod
def _reverse_bytes(data):
"""
Takes data and reverses byte order to fit blowfish-compat format. For example, using _reverse_bytes('12345678')
will return 43218765.
:param data as bytes
:return: reversed bytes
"""
data_size = 0
for n in data:
data_size += 1
reversed_bytes = bytearray()
i = 0
for x in range(0, data_size // 4):
a = (data[i:i + 4])
i += 4
z = 0
n0 = a[z]
n1 = a[z + 1]
n2 = a[z + 2]
n3 = a[z + 3]
reversed_bytes.append(n3)
reversed_bytes.append(n2)
reversed_bytes.append(n1)
reversed_bytes.append(n0)
return bytes(reversed_bytes)