如何删除.net CryptoStream填充

本文关键字:net CryptoStream 填充 删除 何删除 | 更新日期: 2023-09-27 17:59:16

当我使用以下类时,输出是填充的。

public static string EncryptString(string ClearText) {
  byte[] clearTextBytes = Encoding.UTF8.GetBytes(ClearText);
  System.Security.Cryptography.SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
  MemoryStream ms = new MemoryStream();
  byte[] rgbIV = Encoding.ASCII.GetBytes("ryojvlzmdalyglrj");
  byte[] key = Encoding.ASCII.GetBytes("hcxilkqbbhczfeultgbskdmaunivmfuo");            
  CryptoStream cs = new CryptoStream(ms, rijn.CreateEncryptor(key, rgbIV),
           CryptoStreamMode.Write);
  cs.Write(clearTextBytes, 0, clearTextBytes.Length);
  cs.Close();
  return Convert.ToBase64String(ms.ToArray());
}
public static string DecryptString(string EncryptedText)
        {
  byte[] encryptedTextBytes = Convert.FromBase64String(EncryptedText);
  MemoryStream ms = new MemoryStream();
  System.Security.Cryptography.SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
  rijn.Mode = CipherMode.CFB;
  byte[] rgbIV = Encoding.ASCII.GetBytes("ryojvlzmdalyglrj");
  byte[] key = Encoding.ASCII.GetBytes("hcxilkqbbhczfeultgbskdmaunivmfuo"); ;
  CryptoStream cs = new CryptoStream(ms, rijn.CreateDecryptor(key, rgbIV),
  CryptoStreamMode.Write);
  cs.Write(encryptedTextBytes, 0, encryptedTextBytes.Length);
  cs.Close();
  return Encoding.UTF8.GetString(ms.ToArray());
}

我从另一篇帖子中了解到有

rijn.Padding = PaddingMode.None;

当我添加这个时,我得到一个错误,说"要加密的数据长度无效"

即使当我试图加密一个6字节的字符串时,我也会看到一个很长的结果。

var def1 = Encrypt.EncryptString("abcdefg");

给我24个字节!

有人能给我一些建议吗。

更新

更改为以下内容:

        byte[] bytOut = ms.GetBuffer();
        int i = 0;
        for (i = 0; i < bytOut.Length; i++)
            if (bytOut[i] == 0)
                break;
        // convert into Base64 so that the result can be used in xml
        return System.Convert.ToBase64String(bytOut, 0, i);

当我检查bytOut时,它是16字节。然后ToBase64之后返回的值是24字节。我仍然不确定为什么的大小如此之大

如何删除.net CryptoStream填充

您的问题在于操作模式。默认情况是加密块链接(CBC),它要求每个块与算法的块大小匹配,并在必要时使用填充。

您可以使用其他模式。以CFB为例,它会在执行纯ECB模式之前对数据进行内部填充,并在返回结果时切断填充。(并对IVs做一些巧妙的处理,这样你就可以在没有填充的情况下继续使用密码。)但它似乎适合你的情况。

rijn.Mode = CipherMode.CFB;

加密算法在块中工作。它总是四舍五入到最接近的块大小。你只需要一个定义良好的填充算法,这样你就可以在解密后正确地删除填充。