重用ICryptoTransform对象Bug .net 4.6.2 - Azure云服务

时间:2017-10-31 21:06:25

标签: c# azure cryptography azure-cloud-services .net-4.6.2

尝试使用ICryptoTransform在加密和解密期间重复使用AesCryptoServiceProvider个对象时,会出现“错误”错误。通过将应用程序的.NET框架版本升级到4.6.2来解决此问题。

此堆栈溢出帖子(Reuse ICryptoTransform objects)和显示.net版本发行说明(https://github.com/Microsoft/dotnet/blob/master/Documentation/compatibility/aescryptoserviceprovider-decryptor-provides-a-reusable-transform.md)的microsoft github页面解释了此错误以及如何解决此问题。在大多数情况下,当我将我的应用程序升级到.NET版本4.6.2时,这似乎是预期的,对于ASP.NET应用程序有一点点问题 - 在其中一个堆栈溢出注释中提到了解决方案。

但是,在尝试为Azure云服务实现此修复时,所显示的行为就好像框架未更新,无论是否存在上下文切换或项目是否已升级到.NET 4.6.2。

  1. 重用ICryptoTransform对象时,Decrypt方法的字符串输出已损坏。
  2. 使用时忽略上下文切换(当添加到CloudService的app.config中时)。
  3. 注意我只使用本地模拟器对此进行了测试,并且还尝试了以下操作。

    1. 重新安装Nuget包
    2. 升级到.NET 4.7
    3. 使用发行说明中建议的appconfig上下文切换。
    4. 创建新的云服务,行为是一样的。
    5. 任何人都可以确认同样的行为吗?有关升级.NET框架的Azure云服务是否有特殊情况?也许我不知道某个app.config设置?

      代码示例

      private ICryptoTransform _decryptorTransform;
      
      private ICryptoTransform DecryptorTransform
      {
          get
          {
              if (null == _decryptorTransform || !_decryptorTransform.CanReuseTransform)
              {
                  _decryptorTransform?.Dispose();
                  using (var aes = GetNewCryptoProvider())
                  {
                      _decryptorTransform = aes.CreateDecryptor();
                  }
              }
              return _decryptorTransform;
          }
      }
      
      
      public string Encrypt(string plainText, EncodingType type)
      {
          byte[] encrypted;
          using (MemoryStream msEncrypt = new MemoryStream())
          {
              using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, EncryptorTransform, CryptoStreamMode.Write))
              {
                  using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                  {
                      swEncrypt.Write(plainText);
                  }
                  encrypted = msEncrypt.ToArray();
              }
          }
      
          string encryptedString = "";
          if (type == EncodingType.Base32)
              encryptedString = Base32.Encode(encrypted);
          else if (type == EncodingType.Base64)
              encryptedString = Convert.ToBase64String(encrypted);
          else
              throw new NotImplementedException();
      
          if (_azureStorageSafe)
              return encryptedString.Replace('/', '|').Replace('+', '-');
          else
              return encryptedString;
      }
      
      private AesCryptoServiceProvider GetNewCryptoProvider()
      {
          var aes = new AesCryptoServiceProvider();
          aes.Key = keyBytes;
          aes.IV = ivBytes;
          aes.Padding = PaddingMode.Zeros;
          aes.Mode = CipherMode.CBC;
          return aes;
      }
      

0 个答案:

没有答案