C++&;C#调用CryptEncrypt和CryptDecrypt 你好,我想在C++和C之间加密和解密,在这里使用CryptEncrypt wincrypt做了一个DLL项目 C++
但是我有一个解密的问题 出去 加密??r 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代码的
解密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();
}