如何使用非十六进制 IV 对 CBC Blowfish 进行加密
How to CBC Blowfish encrypt with non hex IV
我对加密的工作原理还比较陌生,但是有人要求我使用 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, 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);
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher);
KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(key));
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv, 0, 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, string key, 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, iv, 0, 8);
cipher.Init(false, keyParamWithIV);
byte[] out1 = Hex.Decode(strValue);
byte[] out2 = new byte[cipher.GetOutputSize(out1.Length)];
int len2 = cipher.ProcessBytes(out1, 0, 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, key, newByteIv);
//var newDecryptedValue = Encoding.UTF8.GetBytes(newIv) -- Also tried this, but same result.
at Org.BouncyCastle.Crypto.Paddings.Pkcs7Padding.PadCount(Byte[] input)
at 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 编码。
我对加密的工作原理还比较陌生,但是有人要求我使用 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, 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);
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher);
KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(key));
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv, 0, 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, string key, 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, iv, 0, 8);
cipher.Init(false, keyParamWithIV);
byte[] out1 = Hex.Decode(strValue);
byte[] out2 = new byte[cipher.GetOutputSize(out1.Length)];
int len2 = cipher.ProcessBytes(out1, 0, 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, key, newByteIv);
//var newDecryptedValue = Encoding.UTF8.GetBytes(newIv) -- Also tried this, but same result.
at Org.BouncyCastle.Crypto.Paddings.Pkcs7Padding.PadCount(Byte[] input)
at 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 编码。