java - Blowfish 示例,其中自动填充和取消填充键以调整大小

标签 java encryption cryptography blowfish

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

我想编写一个示例,它将自动填充和取消填充键的大小。由于 Blowfish 创建 8 字节加密输出 block ,因此输出也会被填充和取消填充为 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

最佳答案

因此,该脚本使用了不正确版本的 PKCS#7 填充,当输入大小已可被 block 大小整除时(无论是 key 还是明文),该脚本都不会进行填充。此外,它使用 ECB 模式加密。这两者都不应该在现实生活场景中使用。

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

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

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);
    }
}

关于java - Blowfish 示例,其中自动填充和取消填充键以调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22821419/

相关文章:

java - 如何在特定 IP 地址上运行自己的 LanguageTool 4.0 实例

java.sql.SQLException : Column Index out of range, 0 < 1

c - unsigned char 的打印每次都不同

java - 具有任意标签长度的 AES-GCM

java - 安卓 : Entries cannot be protected with passwords

cryptography - 安全、黑客、密码学阅读?

arrays - 函数应返回 sha256/sha384/sha512 结果作为 byte slice

java - 我应该如何执行一个带有循环的 ArrayList 程序,该循环一次呈现列表的每个索引?

java - AKKA - 如何对处理 TCP 连接的 actor 进行单元测试?

java - 远程创建加密的 MySQL 备份