使用 CBC Blowfish Encryption 加密数据不起作用

问题描述

我正在尝试使用 CBC 河豚加密对 bounycastle 进行加密。这是我无法更改的要求,因此我需要弄清楚这是如何工作的。我对加密完全陌生,因此我非常感谢任何帮助,因为我有一个截止日期要满足。

这是我目前所拥有的:

public void test() {
    var value = "My Test Value";
    var key = "some key"; //56 characters long
    var iv = Encoding.GetBytes("some iv");
    var encryptedValue = CbcBlowfishEncrypt(encryptedText,key,iv);
}

private string CbcBlowfishEncrypt(string strValue,string key,byte[] iv)
{
    byte[] inputBytes = Encoding.UTF8.GetBytes(strValue);
    BlowfishEngine engine = new BlowfishEngine();
    CbcBlockCipher blockCipher = new CbcBlockCipher(engine); //CBC
    PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher); //Default scheme is PKCS5/PKCS7
    KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(key));
    ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam,iv,8);

    cipher.Init(true,keyParamWithIV);
    byte[] outputBytes = new byte[cipher.GetoutputSize(inputBytes.Length)];
    int length = cipher.ProcessBytes(inputBytes,outputBytes,0);
    cipher.DoFinal(outputBytes,length);
    var result = BitConverter.ToString(outputBytes).Replace("-","");
    return result;
}

public static byte[] StringToByteArray(string hex)
{
    return Enumerable.Range(0,hex.Length)
        .Where(x => x % 2 == 0)
        .Select(x => Convert.ToByte(hex.Substring(x,2),16))
        .ToArray();
}

这是我得到的错误

'初始化向量的长度必须与块大小相同'

正如我上面提到的,我对此很陌生,因为客户的截止日期并尽我所能阅读了很多内容并理解它,但我真的在这里碰壁了,不确定从这往哪儿走。这对你们中的一些人来说可能是显而易见的事情,所以请怜悯:)

编辑:要提到的一件事是,我尝试将 ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam,16); 的 16 更改为 8,并且似乎让它通过了。但令我感到困惑的是,我的字节长度为 16 个字节,而不是 8 个字节。这是因为每个字符占用 2 个字节并且该值代表字符,而不是字节?

解决方法

没有人正式发布答案,所以我只是想结束这个问题以帮助其他人尝试做同样的事情。下面是我用来加密和解密值的代码:

function Run()
{
    var key = "enter your key";
    var value = "Enter your test value";
    var iv = StringToByteArray("enter your 16 char hex value");

    var encryptedValue = CbcBlowfishEncrypt(value,key,iv);
    var decryptedValue = CbcBlowfishDecrypt(encryptedValue,iv);
}

private string CbcBlowfishEncrypt(string strValue,string key,byte[] iv)
{
    byte[] inputBytes = Encoding.UTF8.GetBytes(strValue);
    BlowfishEngine engine = new BlowfishEngine();
    CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
    PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher);
    KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(key));
    ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam,iv,8);

    cipher.Init(true,keyParamWithIV);
    byte[] outputBytes = new byte[cipher.GetOutputSize(inputBytes.Length)];
    int length = cipher.ProcessBytes(inputBytes,outputBytes,0);
    cipher.DoFinal(outputBytes,length); //Do the final block
    var c = BitConverter.ToString(outputBytes);
    string encryptedInput = Convert.ToBase64String(outputBytes);
    var result = BitConverter.ToString(outputBytes).Replace("-","");
    return result;
}

private string CbcBlowfishDecrypt(string strValue,byte[] iv)
{
    BlowfishEngine engine = new BlowfishEngine();
    CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
    PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher);
    StringBuilder result = new StringBuilder();
    KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(key));
    ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam,8);

    cipher.Init(false,keyParamWithIV);
    byte[] out1 = Hex.Decode(strValue);
    byte[] out2 = new byte[cipher.GetOutputSize(out1.Length)];
    int len2 = cipher.ProcessBytes(out1,out1.Length,out2,0);
    cipher.DoFinal(out2,len2);
    return Encoding.UTF8.GetString(out2);
}

public static byte[] StringToByteArray(string hex)
{
    return Enumerable.Range(0,hex.Length)
        .Where(x => x % 2 == 0)
        .Select(x => Convert.ToByte(hex.Substring(x,2),16))
        .ToArray();
}