none
[再次求助]AES加密时,模式设置为OFB,报错,出现异常

    问题

  • 将AesCryptoServiceProvider的Mode设为OFB (代码中我注释了一大堆等号的位置),然后就报错了,我也不知道为什么 (报错位置是下面我注释了一大堆加好的地方)。

    以下是代码
    .Net框架版本是4.6.1

    Imports System.IO
    Imports System.Text
    Imports System.Security.Cryptography
    
    Module Module1
    
        Public Function EncryptStringToBytes_Aes(ByVal plainText As String, ByVal Key() As Byte, ByVal IV() As Byte) As Byte()
            Dim encrypted() As Byte
            Using aesAlg As New AesCryptoServiceProvider()
                aesAlg.Mode = CipherMode.OFB '================
                aesAlg.Padding = PaddingMode.PKCS7
                aesAlg.BlockSize = 128 'AES只支持128
                aesAlg.Key = Key
                If aesAlg.Mode <> CipherMode.ECB Then
                    aesAlg.IV = IV
                End If
                Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV) '++++++++++++++++
                Dim msEncrypt As New MemoryStream()
                Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
                    Using swEncrypt As New StreamWriter(csEncrypt)
                        swEncrypt.Write(plainText)
                    End Using
                    encrypted = msEncrypt.ToArray()
                End Using
            End Using
            Return encrypted
        End Function
    
        Sub Main()
            ‘为了方便起见,这里就设定了一个非常简单的key和iv
            Dim key(31) As Byte
            Dim iv(15) As Byte
            Dim i As Integer
            For i = 0 To 31
                key(i) = CByte(i + 1)
                If i <= 15 Then
                    iv(i) = CByte(i + 1)
                End If
            Next i
            Dim temp As Byte() = EncryptStringToBytes_Aes(Console.ReadLine, key, iv) '这里要求用户输入值
        End Sub
    
    End Module

    运行时我输入的内容是:
    123

    然后报错:

    “System.Security.Cryptography.CryptographicException”类型的未经处理的异常在 System.Core.dll 中发生
    其他信息: 出现了内部错误。

    查看错误详细信息:

    未处理System.Security.Cryptography.CryptographicException
      HResult=-2147023537
      Message=出现了内部错误。
    
      Source=System.Core
      StackTrace:
           在 System.Security.Cryptography.CapiNative.SetKeyParameter(SafeCapiKeyHandle key, KeyParameter parameter, Byte[] value)
           在 System.Security.Cryptography.CapiSymmetricAlgorithm.SetupKey(SafeCapiKeyHandle key, Byte[] iv, CipherMode cipherMode, Int32 feedbackSize)
           在 System.Security.Cryptography.AesCryptoServiceProvider.CreateEncryptor(Byte[] key, Byte[] iv)
           在 ConsoleApplication_Test01.Module1.EncryptStringToBytes_Aes(String plainText, Byte[] Key, Byte[] IV) 位置 C:\Users\73744\AppData\Local\Temporary Projects\ConsoleApplication_Test01\Module1.vb:行号 17
           在 ConsoleApplication_Test01.Module1.Main() 位置 C:\Users\73744\AppData\Local\Temporary Projects\ConsoleApplication_Test01\Module1.vb:行号 40
           在 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           在 System.Threading.ThreadHelper.ThreadStart()
      InnerException: 

    两张关于错误信息的截图:(抱歉我等级论坛等级不够不能发图片和链接)

    ht防tps://soc和ial.ms谐dn.micro防soft.co和m/Foru谐ms/getfile/903638
    ht防tps://soc和ial.ms谐dn.micro防soft.co和m/Foru谐ms/getfile/903639

    如果Mode设为CFB、ECB、CBC都正常工作。设为CTS,异常信息是不支持这种模式。

    但这回这个OFB是内部错误,我就搞不懂了。

    求助各位大大,这个是什么原因,怎么解决呢?谢谢

    2016年7月31日 3:05

全部回复

  • 抱歉文末的链接挂了

    img.bbs.csdn.net/upload/201607/26/1469516297_124024.png
    
    img.bbs.csdn.net/upload/201607/26/1469516307_370712.png


    2016年7月31日 3:12
  • 你好,

    我使用你的代码,重新了你的问题。似乎AesCryptoServiceProvider 现在并不支持OFB模式, 我建议你到下面的文档 发布你的建议。(把页面拖到最底下,点 ”否“,在填写你的建议)

    https://msdn.microsoft.com/zh-cn/library/system.security.cryptography.aescryptoserviceprovider(v=vs.110).aspx

    Best regards,

    Cole Wu


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2016年8月16日 9:04
    版主
  • 但是按照AES的标准,应该是要支持OFB模式的啊
    2016年8月27日 2:50
  • 是不支持的原因

    https://social.msdn.microsoft.com/Forums/zh-CN/38b63c4f-ac6c-4bea-b1a7-c3667c5d4e69/ofb?forum=vbasiczhchs

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/891955cd-3125-487c-9746-9fd07f24b12f/why-net-doesnt-support-aes-ofb?forum=netfxbcl

      switch (this.m_cipherMode)
        {
            case CipherMode.CBC:
            case CipherMode.ECB:
                this.m_inputBlockSize = this.m_blockSizeBytes;
                this.m_outputBlockSize = this.m_blockSizeBytes;
                break;

            case CipherMode.CFB:
                this.m_inputBlockSize = feedbackSize / 8;
                this.m_outputBlockSize = feedbackSize / 8;
                break;

            default:
                throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidCipherMode"));
        }

    RijndaelManaged doesn't support OFB mode at the moment. You can code (almost easily) OFB mode yourself, atop of ECB mode, or use side cryptography libraries, like BouncyCastle, SecureBlackbox, whatever else.

    文中提到一个好办法,用.NET Reflector看源代码,就知道原因了。或是用.NET Reflector把程序集导出为源代码,再添加引用此项目,单步调试。


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms


    2016年8月27日 10:02
  • 用.NET Reflector 查看源代码

    没有找到此方法

      System.Security.Cryptography.CapiNative.SetKeyParameter(SafeCapiKeyHandle key, KeyParameter parameter, Byte[] value)

    我用的是.NET 4.0

    ----------------------------------------------------------------------------------------------------------

    namespace System.Security.Cryptography
    {
        using System;
        using System.Runtime.InteropServices;
        using System.Security;

        internal static class CapiNative
        {
            [SecurityCritical]
            internal static SafeCspHandle AcquireCsp(string keyContainer, string providerName, ProviderType providerType, CryptAcquireContextFlags flags)
            {
                if (((flags & (CryptAcquireContextFlags.None | CryptAcquireContextFlags.VerifyContext)) == (CryptAcquireContextFlags.None | CryptAcquireContextFlags.VerifyContext)) && ((flags & CryptAcquireContextFlags.MachineKeyset) == CryptAcquireContextFlags.MachineKeyset))
                {
                    flags &= ~CryptAcquireContextFlags.MachineKeyset;
                }
                SafeCspHandle phProv = null;
                if (!UnsafeNativeMethods.CryptAcquireContext(out phProv, keyContainer, providerName, providerType, flags))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                return phProv;
            }

            [SecurityCritical]
            internal static SafeCspHashHandle CreateHashAlgorithm(SafeCspHandle cspHandle, AlgorithmID algorithm)
            {
                SafeCspHashHandle phHash = null;
                if (!UnsafeNativeMethods.CryptCreateHash(cspHandle, algorithm, IntPtr.Zero, 0, out phHash))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                return phHash;
            }

            [SecurityCritical]
            internal static void GenerateRandomBytes(SafeCspHandle cspHandle, byte[] buffer)
            {
                if (!UnsafeNativeMethods.CryptGenRandom(cspHandle, buffer.Length, buffer))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }

            [SecurityCritical]
            internal static unsafe void GenerateRandomBytes(SafeCspHandle cspHandle, byte[] buffer, int offset, int count)
            {
                fixed (byte* numRef = &(buffer[offset]))
                {
                    if (!UnsafeNativeMethods.CryptGenRandom(cspHandle, count, numRef))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                }
            }

            [SecurityCritical]
            internal static byte[] GetHashProperty(SafeCspHashHandle hashHandle, HashProperty property)
            {
                int pdwDataLen = 0;
                byte[] pbData = null;
                if (!UnsafeNativeMethods.CryptGetHashParam(hashHandle, property, pbData, ref pdwDataLen, 0))
                {
                    int hr = Marshal.GetLastWin32Error();
                    if (hr != 0xea)
                    {
                        throw new CryptographicException(hr);
                    }
                }
                pbData = new byte[pdwDataLen];
                if (!UnsafeNativeMethods.CryptGetHashParam(hashHandle, property, pbData, ref pdwDataLen, 0))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                return pbData;
            }

            [SecurityCritical]
            internal static int GetHashPropertyInt32(SafeCspHashHandle hashHandle, HashProperty property)
            {
                byte[] hashProperty = GetHashProperty(hashHandle, property);
                if (hashProperty.Length != 4)
                {
                    return 0;
                }
                return BitConverter.ToInt32(hashProperty, 0);
            }

            [SecurityCritical]
            internal static byte[] GetKeyProperty(SafeCspKeyHandle keyHandle, KeyProperty property)
            {
                int pdwDataLen = 0;
                byte[] pbData = null;
                if (!UnsafeNativeMethods.CryptGetKeyParam(keyHandle, property, pbData, ref pdwDataLen, 0))
                {
                    int hr = Marshal.GetLastWin32Error();
                    if (hr != 0xea)
                    {
                        throw new CryptographicException(hr);
                    }
                }
                pbData = new byte[pdwDataLen];
                if (!UnsafeNativeMethods.CryptGetKeyParam(keyHandle, property, pbData, ref pdwDataLen, 0))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
                return pbData;
            }

            [SecurityCritical]
            internal static int GetKeyPropertyInt32(SafeCspKeyHandle keyHandle, KeyProperty property)
            {
                byte[] keyProperty = GetKeyProperty(keyHandle, property);
                if (keyProperty.Length != 4)
                {
                    return 0;
                }
                return BitConverter.ToInt32(keyProperty, 0);
            }

            [SecurityCritical]
            internal static void SetHashProperty(SafeCspHashHandle hashHandle, HashProperty property, byte[] value)
            {
                if (!UnsafeNativeMethods.CryptSetHashParam(hashHandle, property, value, 0))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }

            [SecurityCritical]
            internal static bool VerifySignature(SafeCspHandle cspHandle, SafeCspKeyHandle keyHandle, AlgorithmID signatureAlgorithm, AlgorithmID hashAlgorithm, byte[] hashValue, byte[] signature)
            {
                byte[] destinationArray = new byte[signature.Length];
                Array.Copy(signature, destinationArray, destinationArray.Length);
                Array.Reverse(destinationArray);
                using (SafeCspHashHandle handle = CreateHashAlgorithm(cspHandle, hashAlgorithm))
                {
                    if (hashValue.Length != GetHashPropertyInt32(handle, HashProperty.HashSize))
                    {
                        throw new CryptographicException(-2146893822);
                    }
                    SetHashProperty(handle, HashProperty.HashValue, hashValue);
                    if (UnsafeNativeMethods.CryptVerifySignature(handle, destinationArray, destinationArray.Length, keyHandle, null, 0))
                    {
                        return true;
                    }
                    int hr = Marshal.GetLastWin32Error();
                    if (hr != -2146893818)
                    {
                        throw new CryptographicException(hr);
                    }
                    return false;
                }
            }

            internal enum AlgorithmClass
            {
                Any = 0,
                Hash = 0x8000,
                KeyExchange = 0xa000,
                Signature = 0x2000
            }

            internal enum AlgorithmID
            {
                None = 0,
                RsaKeyExchange = 0xa400,
                RsaSign = 0x2400,
                Sha1 = 0x8004,
                Sha256 = 0x800c,
                Sha384 = 0x800d,
                Sha512 = 0x800e
            }

            internal enum AlgorithmSubId
            {
                Any = 0,
                RsaAny = 0,
                Sha1 = 4,
                Sha256 = 12,
                Sha384 = 13,
                Sha512 = 14
            }

            internal enum AlgorithmType
            {
                Any = 0,
                Rsa = 0x400
            }

            [Flags]
            internal enum CryptAcquireContextFlags
            {
                DeleteKeyset = 0x10,
                MachineKeyset = 0x20,
                NewKeyset = 8,
                None = 0,
                Silent = 0x40,
                VerifyContext = -268435456
            }

            internal enum ErrorCode
            {
                BadData = -2146893819,
                BadHash = -2146893822,
                BadSignature = -2146893818,
                MoreData = 0xea,
                NoKey = -2146893811,
                Ok = 0
            }

            internal enum HashProperty
            {
                HashSize = 4,
                HashValue = 2,
                None = 0
            }

            [Flags]
            internal enum KeyGenerationFlags
            {
                Archivable = 0x4000,
                Exportable = 1,
                None = 0,
                UserProtected = 2
            }

            internal enum KeyProperty
            {
                AlgorithmID = 7,
                KeyLength = 9,
                None = 0
            }

            internal enum KeySpec
            {
                KeyExchange = 1,
                Signature = 2
            }

            internal static class ProviderNames
            {
                internal const string MicrosoftEnhanced = "Microsoft Enhanced Cryptographic Provider v1.0";
            }

            internal enum ProviderType
            {
                RsaFull = 1
            }

            [SecurityCritical]
            internal static class UnsafeNativeMethods
            {
                [return: MarshalAs(UnmanagedType.Bool)]
                [DllImport("advapi32", CharSet=CharSet.Unicode, SetLastError=true)]
                internal static extern bool CryptAcquireContext(out SafeCspHandle phProv, string pszContainer, string pszProvider, CapiNative.ProviderType dwProvType, CapiNative.CryptAcquireContextFlags dwFlags);
                [return: MarshalAs(UnmanagedType.Bool)]
                [DllImport("advapi32", SetLastError=true)]
                internal static extern bool CryptCreateHash(SafeCspHandle hProv, CapiNative.AlgorithmID Algid, IntPtr hKey, int dwFlags, out SafeCspHashHandle phHash);
                [return: MarshalAs(UnmanagedType.Bool)]
                [DllImport("advapi32", SetLastError=true)]
                internal static extern bool CryptGenKey(SafeCspHandle hProv, int Algid, uint dwFlags, out SafeCspKeyHandle phKey);
                [return: MarshalAs(UnmanagedType.Bool)]
                [DllImport("advapi32", SetLastError=true)]
                internal static extern bool CryptGenRandom(SafeCspHandle hProv, int dwLen, [In, Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbBuffer);
                [return: MarshalAs(UnmanagedType.Bool)]
                [DllImport("advapi32", SetLastError=true)]
                internal static extern unsafe bool CryptGenRandom(SafeCspHandle hProv, int dwLen, byte* pbBuffer);
                [return: MarshalAs(UnmanagedType.Bool)]
                [DllImport("advapi32", SetLastError=true)]
                internal static extern bool CryptGetHashParam(SafeCspHashHandle hHash, CapiNative.HashProperty dwParam, [In, Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbData, [In, Out] ref int pdwDataLen, int dwFlags);
                [return: MarshalAs(UnmanagedType.Bool)]
                [DllImport("advapi32", SetLastError=true)]
                internal static extern bool CryptGetKeyParam(SafeCspKeyHandle hKey, CapiNative.KeyProperty dwParam, [In, Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbData, [In, Out] ref int pdwDataLen, int dwFlags);
                [return: MarshalAs(UnmanagedType.Bool)]
                [DllImport("advapi32", SetLastError=true)]
                internal static extern bool CryptImportKey(SafeCspHandle hProv, [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbData, int pdwDataLen, IntPtr hPubKey, CapiNative.KeyGenerationFlags dwFlags, out SafeCspKeyHandle phKey);
                [return: MarshalAs(UnmanagedType.Bool)]
                [DllImport("advapi32", SetLastError=true)]
                internal static extern bool CryptSetHashParam(SafeCspHashHandle hHash, CapiNative.HashProperty dwParam, [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbData, int dwFlags);
                [return: MarshalAs(UnmanagedType.Bool)]
                [DllImport("advapi32", CharSet=CharSet.Unicode, SetLastError=true)]
                internal static extern bool CryptVerifySignature(SafeCspHashHandle hHash, [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbSignature, int dwSigLen, SafeCspKeyHandle hPubKey, string sDescription, int dwFlags);
            }
        }
    }


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2016年8月27日 10:13
  • 找到一点蛛丝马迹,看能否帮助到你

    namespace System.Security.Cryptography
    {
        using System;
        using System.Runtime.InteropServices;

        [Serializable, ComVisible(true)]
        public enum CipherMode
        {
            CBC = 1,
            CFB = 4,
            CTS = 5,
            ECB = 2,
            OFB = 3
        }
    }

    The Output Feedback (OFB) mode processes small increments of plain text into
    cipher text instead of processing an entire block at a time. This mode is
    similar to CFB; the only difference between the two modes is the way that the
    shift register is filled. If a bit in the cipher text is mangled, the
    corresponding bit of plain text will be mangled. However, if there are extra or
    missing bits from the cipher text, the plain text will be mangled from that
    point on.


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2016年8月27日 10:19
  • 不是太懂,我是.Net新人
    2016年8月27日 11:55
  • 没有找到此方法会不会是因为4.6.1和4.0在编译的时候的IL不一样?
    2016年8月27日 11:57
  • public 方法一定会存在的,我用的是.NET 4.6。


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2016年8月27日 15:28