我在C DLL中具有执行SCrypt密钥派生的功能,但是在将值编组到我的C#程序中时遇到了真正的麻烦。
函数声明在C中如下所示:
__declspec(dllexport) int scrypt(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,uint8_t * buf, size_t buflen);
passwd和salt都在指向uint8数组的指针中传递,N,r和p是算法的调整值。Buflen是您希望输出缓冲区为的大小。buf是输出缓冲区(所以我认为需要是ref或out);
我尝试了各种方法,最近的方法是Marshal.Copy,将数据从IntPtrs中移出到字节数组中(反之亦然),但是由于这些是UInt指针而不是IntPtr,所以我不知道那是不是对。目前,当我尝试从buf IntPtr中复制数据并将其复制回数组时,它会崩溃。
非常感谢您的协助。
class Program
{
[DllImport("SCrypt.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern int scrypt(IntPtr passwd, UIntPtr passwdlen, IntPtr salt, UIntPtr saltlen, UInt64 N, UInt32 r, UInt32 p, out IntPtr buf, UIntPtr buflen);
static void Main(string[] args)
{
byte[] encoded = new byte[32];
IntPtr encodedptr;
byte[] password = System.Text.Encoding.Unicode.GetBytes("test");
byte[] salt = System.Text.Encoding.Unicode.GetBytes("ThisistheSaltweareusingforthiskey");
IntPtr passwordptr, saltptr;
passwordptr = Marshal.AllocHGlobal(password.Length);
Marshal.Copy(password, 0, passwordptr, password.Length);
saltptr = Marshal.AllocHGlobal(salt.Length);
Marshal.Copy(salt, 0, saltptr, salt.Length);
int returnVal = scrypt(passwordptr, (UIntPtr)password.Length, saltptr, (UIntPtr)salt.Length, 262144, 8, 1,out encodedptr,(UIntPtr) 32);
Marshal.Copy(encodedptr, encoded, 0, 32);
Console.WriteLine(BitConverter.ToString(encoded));
Console.ReadKey();
}
}
我可能会使用以下函数声明:
public static extern int scrypt(byte[] passwd, uint passwdlen, byte[] salt, uint saltlen, ulong N, uint r, uint p, byte[] buf, uint buflen).
请记住,封送某些类型有多种不同的方式,但是在这种情况下,上述变体可能是最清晰的,因为它直接映射到各个类型。
您可以要求astring
来简单地将a转换为a 。对于密码,只要您转换为Unicode,一切都应该没问题。但是请确保在可能需要将密码转换为的每个位置使用相同的变体。byte[]
Encoding
byte[]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句