Blowfish示例,其中自动填充和取消键大小的键

时间:2014-04-02 19:43:05

标签: java encryption cryptography blowfish

Blowfish能够进行强加密,并且可以使用最大56字节的密钥大小(448位密钥)。  密钥必须是8个字节的倍数(最多56个字节)。

我想写的例子会自动填充和取消键盘的大小。因为Blowfish创建了8字节加密输出的块,所以输出也被填充并且未填充到8字节的倍数。

实际上想要编写java代码来模拟 - http://webnet77.com/cgi-bin/helpers/blowfish.pl

我正在使用工具信息 -

ALGORITM = "Blowfish";
HEX KEY = "92514c2df6e22f079acabedce08f8ac3";
PLAIN_TEXT = "sangasong@song.com"

工具返回 -

CD3A08381467823D4013960E75E465F0B00C5E3BAEFBECBB 

请建议。

尝试了java代码:

public class TestBlowfish
{
    final String KEY = "92514c2df6e22f079acabedce08f8ac3";
    final String PLAIN_TEXT = "sangasong@song.com";
    byte[] keyBytes = DatatypeConverter.parseHexBinary(KEY); 
}

public static void main(String[] args) throws Exception 
{
    try 
    {
        byte[] encrypted = encrypt(keyBytes, PLAIN_TEXT);
        System.out.println( "Encrypted hex: " + Hex.encodeHexString(encrypted));

    }catch (GeneralSecurityException e) 
    {
        e.printStackTrace();
    }
}

private static byte[] encrypt(byte[] key, String plainText) throws GeneralSecurityException
{
    SecretKey secret_key = new SecretKeySpec(key, "Blowfish");
    Cipher cipher = Cipher.getInstance("Blowfish");
    cipher.init(Cipher.ENCRYPT_MODE, secret_key);

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

结果 -

Encrypted hex: 525bd4bd786a545fe7786b0076b3bbc2127425f0ea58c29d

2 个答案:

答案 0 :(得分:2)

因此,当输入的大小已经被块大小分割时,脚本使用了不正确的PKCS#7填充版本 - 无论是密钥还是明文。此外,它使用ECB模式加密。这些都不应该用在现实生活中。

以下代码要求将Bouncy Castle提供程序添加到JCE(Service.addProvider(new BouncyCastleProvider())),并且Hex类的Bouncy Castle库位于类路径中。

警告:仅在输入有限的情况下进行测试,如果密钥的大小大于最大值,则不会削减密钥大小。

enter image description here

警告:以下代码不是加密的声音

import org.bouncycastle.util.encoders.Hex;

public class BadBlowfish {
        private static SecretKey createKey(String theKey) {
        final byte[] keyData = theKey.getBytes(StandardCharsets.US_ASCII);
        final byte[] paddedKeyData = halfPadPKCS7(keyData, 8);
        SecretKey secret = new SecretKeySpec(paddedKeyData, "Blowfish");
        return secret;
    }

    private static byte[] halfUnpadPKCS7(final byte[] paddedPlaintext, int blocksize) {
        int b = paddedPlaintext[paddedPlaintext.length - 1] & 0xFF;
        if (b > 0x07) {
            return paddedPlaintext.clone();
        }
        return Arrays.copyOf(paddedPlaintext, paddedPlaintext.length - b);
    }

    private static byte[] halfPadPKCS7(final byte[] plaintext, int blocksize) {
        if (plaintext.length % blocksize == 0) {
            return plaintext.clone();
        }

        int newLength = (plaintext.length / blocksize + 1) * blocksize;
        int paddingLength = newLength - plaintext.length;

        final byte[] paddedPlaintext = Arrays.copyOf(plaintext, newLength);
        for (int offset = plaintext.length; offset < newLength; offset++) {
            paddedPlaintext[offset] = (byte) paddingLength;
        }
        return paddedPlaintext;
    }

    public static void main(String[] args) throws Exception {
        Cipher cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
        SecretKey key = createKey("123456781234567");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] plaintextData = cipher.doFinal(Hex.decode("085585C60B3D23257763E6D8BB0A0891"));
        byte[] unpaddedPlaintextData = halfUnpadPKCS7(plaintextData, cipher.getBlockSize());

        String plaintextHex = Hex.toHexString(unpaddedPlaintextData);
        System.out.println(plaintextHex);
        String plaintext = new String(unpaddedPlaintextData, StandardCharsets.UTF_8);
        System.out.println(plaintext);
    }
}

答案 1 :(得分:0)

我不确定这个问题的相关性:恕我直言,没有必要获得与此脚本相同的输出:你没有保证它是多么安全/有效...... 令我垂涎欲滴的是关于填充的部分:有几个解决方案来填充块,其中一些很简单但非常不安全,可能这个脚本使用其中一个&#34;坏& #34;溶液

您是否检查过您的程序是否能够检索到正确的纯文本? (您需要对匹配的decrypt函数进行编码)。 如果是这样,这意味着它可以正常工作,它可以用于任何你原来的目的,无论这个脚本的输出是什么......