微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用非十六进制 IV 进行 CBC Blowfish 加密

如何解决如何使用非十六进制 IV 进行 CBC Blowfish 加密

我对加密的工作原理很陌生,但是,有人要求我使用 Blowfish CBC 加密对值进行加密和解密。现在我已经花了很多时间在这上面,我认为我是正确的,直到他们给我发送了他们希望我使用的 IV,这让我非常困惑。我的印象是 IV 必须是一个十六进制值,但是,他们给我发送了一个 IV,它看起来像:cl5PxDOt

我设法生成代码如下所示:

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

我希望有人能告诉我如何修改上面的代码以使用以下示例 iv:cl5PxDOt

编辑:这是我尝试过的,但我每次都得到 pad block corrupted

var newIv = "cl5PxDOt";
var newByteIv = newIv.ToArray().Select(Convert.ToByte).ToArray();
var newDecryptedValue = CbcBlowfishDecrypt(ospToken,newByteIv);
//var newDecryptedValue = Encoding.UTF8.GetBytes(newIv) -- Also tried this,but same result.

在 Org.BouncyCastle.Crypto.Paddings.Pkcs7Padding.PadCount(Byte[] input)
在 Org.BouncyCastle.Crypto.Paddings.PaddedBufferedBlockCipher.DoFinal(Byte[] output,Int32 outOff)

解决方法

如果密钥不是 Base64 解码而是 UTF-8 编码,则可以解密密文,即在 CbcBlowfishDecrypt()(和 CbcBlowfishEncrypt())行中

KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(key));

被替换为

KeyParameter keyParam = new KeyParameter(Encoding.UTF8.GetBytes(key));

UTF-8 编码的密钥长度为 448 位,因此是一个有效的密钥(Blowfish 是为 32 到 448 位之间的密钥长度定义的)。

IV 可以以模拟方式进行 UTF-8 编码,而不是当前的实现方式。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。