【问题标题】:java and Python implementation of Blowfish produce different resultsBlowfish 的 java 和 Python 实现产生不同的结果
【发布时间】:2016-04-18 02:24:48
【问题描述】:

我在 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 表示 pycrypto 的河豚实现存在问题。但是,我可以确认接受的答案 here 有效。不知道为什么。我尝试了 pycrypto 和 this blowfish module,结果相同。

任何想法如何在 Python 中复制与遗留 Java 代码相同的河豚输出?

【问题讨论】:

  • 似乎您的 java 代码使用了河豚的 ECB 模式您是否检查过 pyhon 也在 ECB 中运行,而不是在 CBC 或其他模式下运行?
  • 我正在使用cipher = Blowfish.new(key_str, Blowfish.MODE_ECB)。那不是将python河豚设置为ECB模式吗?
  • 是的,你的权利,经过一番自我检查后,我认为 python 实际上为河豚产生了正确的结果。和 java 似乎是河豚紧凑型
  • 什么是河豚紧凑型?你能详细说明一下吗?有没有办法在 python 上实现它?
  • 以前从未听说过它,但我现在在一个工具中看到它,以便在测试时选择作为选项。似乎它是由一个错误创建的,当时有人没有按照算法指定的方式在河豚加密中使用大端字节序。这里已经有一个问题:stackoverflow.com/questions/11422497/…

标签: java python-3.x pycrypto blowfish


【解决方案1】:

感谢@Kai Iskratsch 指出了正确的方向。

参考:

  1. What's the difference between Blowfish and Blowfish-compat?

  2. https://gist.github.com/adamb70/1f140573b37939e78eb5%22

这是对我有用的代码。

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    相关资源
    最近更新 更多