在C#中使用OpenSSL库的SHA256方法
Using SHA256 method of OpenSSL library in C#
我正在为 C# 的 OpenSSL 编写包装器,实际上现在一切正常,但我在使用一种方法时遇到问题。 (我知道 OpenSSL.Net,它只是不能按我的需要工作,而且缺少很多方法)。
OpenSSL 1.0.1 具有我想要使用的 SHA256。 OpenSSL lib C 代码中的方法本身:
unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
{
SHA256_CTX c;
static unsigned char m[SHA256_DIGEST_LENGTH];
if (md == NULL)
md = m;
SHA256_Init(&c);
SHA256_Update(&c, d, n);
SHA256_Final(md, &c);
OPENSSL_cleanse(&c, sizeof(c));
return (md);
}
函数本身 returns 一个指针,作为参数,它需要输入数据、要散列的数据长度和散列对象。
我用下一种方式包装它:
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static IntPtr SHA256(byte[] data, long len, ref byte[] result);
我正在尝试 运行 下一个方法:
byte[] d = Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaa");
byte[] r = new byte[32];
IntPtr x = NOpenSSL.Wrapper.SHA256(d, d.Length, ref r);
Console.WriteLine(d.Length + " " + x + " " + r.Length + " " + Encoding.ASCII.GetString(r));
我得到的结果是:16 1838788744 1
。 d.Length
是 16 OK,我得到 x 作为指针 OK,r.Length
变成 1 个字节,这是不可能的。
如果我不 ref
方法中的 byte[]
只是简单地给它变量 r
.
没有任何变化
谁能帮帮我,我做错了什么?
提前感谢您的帮助!
在发现 OpenSSL C 源代码并尝试使用 C# 指针和编组后,发现 SHA256
方法并未将结果散列放入变量 md
,但它 returns 指向散列的指针。 (起初我以为它是 SHA256 结构的指针,但它是实际的哈希值。)
工作的 C# 代码如下:
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static IntPtr SHA256(byte[] data, long len, byte[] result);
-
byte[] data = Encoding.ASCII.GetBytes("some_data_to_hash");
IntPtr r = NOpenSSL.Wrapper.SHA256(data, data.Length, null);
byte[] output = new byte[32];
Marshal.Copy(r, output, 0, output.Length);
// output contains now the 32 bytes of the hashed data
因为我们没有使用 SHA256
方法的第三个变量(我们只是传递 null
而不是),所以需要从 DllImport
中删除 ref
.
(注意:https://www.openssl.org/docs/manmaster/crypto/sha.html说:如果md为NULL,则摘要放在静态数组中。注意:将md设置为NULL不是线程安全的。)
使用SHA512
是完全一样的,只是我们需要替换代码中两处的方法名,并将output
byte[] length
从32
到 64
.
我正在为 C# 的 OpenSSL 编写包装器,实际上现在一切正常,但我在使用一种方法时遇到问题。 (我知道 OpenSSL.Net,它只是不能按我的需要工作,而且缺少很多方法)。
OpenSSL 1.0.1 具有我想要使用的 SHA256。 OpenSSL lib C 代码中的方法本身:
unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
{
SHA256_CTX c;
static unsigned char m[SHA256_DIGEST_LENGTH];
if (md == NULL)
md = m;
SHA256_Init(&c);
SHA256_Update(&c, d, n);
SHA256_Final(md, &c);
OPENSSL_cleanse(&c, sizeof(c));
return (md);
}
函数本身 returns 一个指针,作为参数,它需要输入数据、要散列的数据长度和散列对象。
我用下一种方式包装它:
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static IntPtr SHA256(byte[] data, long len, ref byte[] result);
我正在尝试 运行 下一个方法:
byte[] d = Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaa");
byte[] r = new byte[32];
IntPtr x = NOpenSSL.Wrapper.SHA256(d, d.Length, ref r);
Console.WriteLine(d.Length + " " + x + " " + r.Length + " " + Encoding.ASCII.GetString(r));
我得到的结果是:16 1838788744 1
。 d.Length
是 16 OK,我得到 x 作为指针 OK,r.Length
变成 1 个字节,这是不可能的。
如果我不 ref
方法中的 byte[]
只是简单地给它变量 r
.
谁能帮帮我,我做错了什么?
提前感谢您的帮助!
在发现 OpenSSL C 源代码并尝试使用 C# 指针和编组后,发现 SHA256
方法并未将结果散列放入变量 md
,但它 returns 指向散列的指针。 (起初我以为它是 SHA256 结构的指针,但它是实际的哈希值。)
工作的 C# 代码如下:
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static IntPtr SHA256(byte[] data, long len, byte[] result);
-
byte[] data = Encoding.ASCII.GetBytes("some_data_to_hash");
IntPtr r = NOpenSSL.Wrapper.SHA256(data, data.Length, null);
byte[] output = new byte[32];
Marshal.Copy(r, output, 0, output.Length);
// output contains now the 32 bytes of the hashed data
因为我们没有使用 SHA256
方法的第三个变量(我们只是传递 null
而不是),所以需要从 DllImport
中删除 ref
.
(注意:https://www.openssl.org/docs/manmaster/crypto/sha.html说:如果md为NULL,则摘要放在静态数组中。注意:将md设置为NULL不是线程安全的。)
使用SHA512
是完全一样的,只是我们需要替换代码中两处的方法名,并将output
byte[] length
从32
到 64
.