【问题标题】:Issues with BlowFish Encryption/Decryption (JBoss Encryption)BlowFish 加密/解密问题(JBoss 加密)
【发布时间】:2013-01-23 23:54:50
【问题描述】:

这是我在使用 BlowFish 加密/解密时遇到的问题。

以下代码用于测试 BlowFish 加密/解密

// Code below omits comments for Brevity

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

import java.math.BigInteger;

public class JBoss {

    public static void main(String[] args) throws Exception {

        if ((args.length != 2)
                || !(args[0].equals("-e") | args[0].equals("-d"))) {
            System.out
                    .println("Usage:\n\tjava JBoss <-e|-d> <encrypted_password>");
            return;
        }

        String mode = args[0];

        byte[] kbytes = "jaas is the way".getBytes();
        SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");
        Cipher cipher = Cipher.getInstance("Blowfish");

        String out = null;

        if (mode.equals("-e")) {
            String secret = args[1];
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encoding = cipher.doFinal(secret.getBytes());
            out = new BigInteger(encoding).toString(16);
        } else {
            BigInteger secret = new BigInteger(args[1], 16);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] encoding = cipher.doFinal(secret.toByteArray());
            out = new String(encoding);
        }
        System.out.println(out);
    }
}

现在,如果我尝试加密字符串

u7mzqw2

我得到的值是

-7ccb7ff0c2858a

如果我尝试解密

-7ccb7ff0c2858a

我得到如下错误:

    java JBoss -d -7ccb7ff0c2858a
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
        at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
        at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
        at com.sun.crypto.provider.BlowfishCipher.engineDoFinal(DashoA13*..)
        at javax.crypto.Cipher.doFinal(DashoA13*..)
        at JBoss.main(JBoss.java:41)

整个代码是here

如果我没记错的话,它与 7 个字符长度的原始值或非 /8=0 加密值无关,如下所示

java JBoss -e qwerty

-40e961f375c2eee6

java JBoss -d -40e961f375c2eee6

qwerty

我错过了什么??

【问题讨论】:

  • 你为什么要转换成BigInteger
  • 这是一个获取十六进制字符串的技巧,在 bigints 被签名的意义上它是棘手的,它当然远非理想。
  • 不是我想要的,这似乎是 JBoss 中的实现方式。请查看此链接 (usefulfor.com/security/2009/09/24/…)

标签: encryption jboss blowfish password-encryption initialization-vector


【解决方案1】:

这是我的观察:我稍微修改了代码,添加了一些带有单个字节和相应十六进制值的 sops。

输入: asdfda

16::10

60::3c

105::69

57::39

-60::-3c

110::6e

19::13

-52::-34

编码值:103c6939c46e13cc

如您所见,左边的项目是字节,右边是基数为 16 的单个大整数,底部是编码值。你可能会看到一个大的模式匹配。除了带有 -tive 的值。像 -60 对应值 -3c ,但与 1 字节转换一样,该值变为 c4 (见 yourslef)。

现在我测试了加密为 u7mzqw2 的值,让我们看看会发生什么。

输入: u7mzqw2

-1::-1

-125::-7d

52::34

-128::-80

15::f

61::3d

122::7a

118::76

编码值:-7ccb7ff0c2858a

现在你看到模式匹配了,现在你不会了,为什么不呢?让我们看看,-1 的十六进制应该是 -1 吗? ??? ,不,它是 0XFF,现在我们可以用 Byte 表示 0xFF 吗?不,我们不能。读自己Byte and -1

更新:让我感到困惑的是这些编码是如何评估的?还在找,帮我看看这个

【讨论】:

  • 经验教训:每当你得到一个加密字符串,确保你的解密逻辑将处理正确的响应,不要假设:):)
  • 我在 java.security.MessageDigest 类的帮助下将字符串转换为 base 64,它有时会在给出输出字符串时跳过 1 个字符,因此该方法中可能存在一些错误。我现在改变了方法,现在它工作正常。加密和解密是复杂的事情。
【解决方案2】:

试试这个,

public static void main(String[] args) throws Exception {
     // generate key
     KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish");
     SecretKey secretKey = keyGen.generateKey();
     // get Cipher and init it for encryption
     Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
     cipher.init(Cipher.ENCRYPT_MODE, secretKey);
     String data="u7mzqw2";

     // encrypt data
     byte[] cipherText = cipher.doFinal(data.getBytes());
     // get the initialization vector from the cipher
     byte[] ivBytes = cipher.getIV();
     IvParameterSpec iv = new IvParameterSpec(ivBytes);

     byte[] keyBytes = secretKey.getEncoded();
     // create a SecretKeySpec from key material
     SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "Blowfish");
     // get Cipher and init it for encryption
     cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
     cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv);
     byte[] plainText = cipher.doFinal(cipherText);
     System.out.println(new String(plainText));
}

【讨论】:

  • 我不认为OP有更改代码的选项,提供的源是Jboss给出的默认实现
【解决方案3】:

如果我们查看 secret.toByteArray() 中的以下代码行给出长度为 7 字节的数组,这应该是问题的原因。

byte[] encoding = cipher.doFinal(secret.toByteArray()); //During decoding logic

问题似乎出在BlowfishCipher,CipherCore 的实现中。

public BlowfishCipher()
{
        core = new CipherCore(new BlowfishCrypt(),
                              BlowfishConstants.BLOWFISH_BLOCK_SIZE);
}

http://www.docjar.com/html/api/com/sun/crypto/provider/BlowfishConstants.java.html

我们正在使用 BlowfishConstants.BLOWFISH_BLOCK_SIZE = 8; // 字节数

http://hg.openjdk.java.net/jdk6/jdk6/jdk/raw-file/2d585507a41b/src/share/classes/com/sun/crypto/provider/CipherCore.java

if ((paddingLen > 0) && (paddingLen != blockSize) &&
            (padding != null) && decrypting) {
            throw new IllegalBlockSizeException
                ("Input length must be multiple of " + blockSize +
                 "when decrypting with padded cipher");
        }

【讨论】:

  • BlowfishCipher 没有问题,密码给出了一个加密的字节数组,其大小始终为 8 的倍数,当使用 BigInteger 将其转换为十六进制字符串时,原始字节数组被打乱反之亦然
  • 注意:在加密和解密过程中,我们看到长度为 7 的字节数组,用于“u7mzqw2”密码,所以这是解密失败的问题加密工作
  • 抱歉在加密过程中我们看到长度为 8 字节的数组
猜你喜欢
  • 1970-01-01
  • 2015-09-25
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 2011-07-30
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
相关资源
最近更新 更多