Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++&;C#调用CryptEncrypt和CryptDecrypt 你好,我想在C++和C之间加密和解密,在这里使用CryptEncrypt wincrypt做了一个DLL项目 C++_C#_C++ - Fatal编程技术网

C++&;C#调用CryptEncrypt和CryptDecrypt 你好,我想在C++和C之间加密和解密,在这里使用CryptEncrypt wincrypt做了一个DLL项目 C++

C++&;C#调用CryptEncrypt和CryptDecrypt 你好,我想在C++和C之间加密和解密,在这里使用CryptEncrypt wincrypt做了一个DLL项目 C++,c#,c++,C#,C++,但是我有一个解密的问题 出去 加密??r c? 解密datatestx 加密1?8V?6N5l??? 解密 d- 正如您所看到的,解密是错误的,可能是错误的首先,您的C/C++代码使用了不推荐的Windows函数,其次,使用了很多“不安全”的C运行时函数,如:“strcpy”、“strcat”、“sprintf”等,第三,并非所有代码都在防止缓冲区编码错误。C代码原样在最近的Visual Studio编译器中编译时没有进行重大更正 请尝试修复所有错误,简化代码并再次发布 在C#端,传递给C代码的

但是我有一个解密的问题

出去

加密??r c?
解密datatestx

加密1?8V?6N5l???
解密 d-


正如您所看到的,解密是错误的,可能是错误的

首先,您的C/C++代码使用了不推荐的Windows函数,其次,使用了很多“不安全”的C运行时函数,如:“strcpy”、“strcat”、“sprintf”等,第三,并非所有代码都在防止缓冲区编码错误。C代码原样在最近的Visual Studio编译器中编译时没有进行重大更正

请尝试修复所有错误,简化代码并再次发布

在C#端,传递给C代码的数据缓冲区不固定,GC可以随时移动。由于它的小尺寸,GC可以急切地将它们从第0代提升到第1代,这将导致内存移动操作和指向缓冲区的指针失效。简单地说,指向所有缓冲区的指针在被C代码读取时可能无效

在C侧,您可以执行以下操作:

    [DllImport("Project3.dll", CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static unsafe extern bool EncryptData(
        byte* szData, char* szPassword, StringBuilder sbError, byte* pData, byte* pDataLen, bool Encrypt);

    static unsafe void Main(string[] args)
    {
        StringBuilder sbError = new StringBuilder(255);
        byte[] szDataBuff = Encoding.ASCII.GetBytes("datatest");
        char[] szPasswordBuff = ("test").ToCharArray();
        byte[] pDataBuff = new byte[1008];
        byte[] pDataLenBuff = new byte[16];

        fixed (byte* szData = szDataBuff)
        fixed (char* szPassword = szPasswordBuff)
        fixed (byte* pData = pDataBuff)
        fixed (byte* pDataLen = pDataLenBuff)
        {
            Console.WriteLine("Encrypt");
            bool bRet = EncryptData(szData, szPassword, sbError, pData, pDataLen, true);

            Console.WriteLine("Encrypted: {0}", bRet);
            Console.WriteLine(Marshal.PtrToStringAnsi((IntPtr)pData));

            Console.WriteLine("Decrypt");
            bool bRet2 = EncryptData(szData, szPassword, sbError, pData, pDataLen, false);
            Console.WriteLine("Derypted: {0}", bRet2);
            Console.WriteLine(Marshal.PtrToStringAnsi((IntPtr)pData));
        }

        Console.ReadKey();
    }

还有其他可能的方法,但这一种似乎是最直接和简单的。

加密数据的
的最后一个参数对于加密是true,但是对于C#code中的加密,您用
false
来调用它。还建议阅读:是的,我只是注意到我忘记了我删除了,但仍然解密不工作。学习如何调试小程序,最小化重现问题所需的源代码,并将其发布在这里。“我的代码不工作”不是问题。C++代码中的StrLeN(SZDATA)假定SZDATA是一个零终止的C字符串。所以不是字节[],没有零终止符。
namespace ConsoleApp1
{
    class Program
    {
        [DllImport("Project3.dll", CallingConvention = CallingConvention.Cdecl)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EncryptData(byte[] szData, char[] szPassword, StringBuilder sbError, byte[] pData, byte[] pDataLen, bool Encrypt);

        static void Main(string[] args)
        {

            StringBuilder sbError = new StringBuilder(255);
            byte[] szData = Encoding.ASCII.GetBytes("datatest");
            char[] szPassword = ("test").ToCharArray();
            byte[] pData = new byte[1008];
            byte[] pDataLen = new byte[16];
            Console.WriteLine("Encrypt");
            bool bRet = EncryptData(szData, szPassword, sbError, pData, pDataLen, true);

            Console.WriteLine(Encoding.ASCII.GetString(pData));

            Console.WriteLine("Decrypt");
            bool bRet2 = EncryptData(szData, szPassword, sbError, pData, pDataLen, false);
            Console.WriteLine(Encoding.ASCII.GetString(pData));

            Console.ReadKey();

        }
    }
}
    [DllImport("Project3.dll", CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static unsafe extern bool EncryptData(
        byte* szData, char* szPassword, StringBuilder sbError, byte* pData, byte* pDataLen, bool Encrypt);

    static unsafe void Main(string[] args)
    {
        StringBuilder sbError = new StringBuilder(255);
        byte[] szDataBuff = Encoding.ASCII.GetBytes("datatest");
        char[] szPasswordBuff = ("test").ToCharArray();
        byte[] pDataBuff = new byte[1008];
        byte[] pDataLenBuff = new byte[16];

        fixed (byte* szData = szDataBuff)
        fixed (char* szPassword = szPasswordBuff)
        fixed (byte* pData = pDataBuff)
        fixed (byte* pDataLen = pDataLenBuff)
        {
            Console.WriteLine("Encrypt");
            bool bRet = EncryptData(szData, szPassword, sbError, pData, pDataLen, true);

            Console.WriteLine("Encrypted: {0}", bRet);
            Console.WriteLine(Marshal.PtrToStringAnsi((IntPtr)pData));

            Console.WriteLine("Decrypt");
            bool bRet2 = EncryptData(szData, szPassword, sbError, pData, pDataLen, false);
            Console.WriteLine("Derypted: {0}", bRet2);
            Console.WriteLine(Marshal.PtrToStringAnsi((IntPtr)pData));
        }

        Console.ReadKey();
    }