Pinvoking adwapi.dll-cryptDecrypt和cryptEncrypt函数,奇怪的问题 [英] Pinvoking adwapi.dll - cryptDecrypt and cryptEncrypt functions, weird problem

查看:104
本文介绍了Pinvoking adwapi.dll-cryptDecrypt和cryptEncrypt函数,奇怪的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在观察此函数的异常行为,我要加密的字符串包含14个字节,如果我使用该函数发送缓冲区长度= 14,则它将失败(内部错误"-非常具有描述性且最有帮助错误代码),但当缓冲区长度(以及缓冲区本身)为128字节大时有效.

I am observing wierd behaviour of this function, the string that I want to encrypt contains 14 bytes, if I use the function to send lenght of buffer = 14, it fails ("an internal error" - very descriptive and most helpful error code), but it works when the buffer length (and the buffer itself) is 128 bytes large.

我通过制作一个大小为128字节的数组克服了这个问题,并从纯文本(希望加密)中复制了14个字节,

I overcame this problem by making a size 128 byte array and I copied the 14 bytes from the plain text (that I wish to encrypt),

当我解密这些字节时,我必须再次为该函数提供整个128字节的数组(现在,每个字节都已加密,甚至是#13-#127中的(我想也是可以预期的)).对我来说幸运的是,前14个字节已按应有的方式解密,其余的都是乱码.

When I decrypt those bytes, I must once again give the function the whole 128 byte array (which now has every byte encrypted, even the ones from #13-#127 (which I guess is to be expected)). Luckily for me the first 14 bytes get decrypted as they should, the rest is gibberish.

我想知道为什么传入的缓冲区不是128字节大时,加密方法会失败,为什么解密函数也需要128字节数组,这是填充的事情吗?

I would like to know why the encrypt method fails if the incoming buffer isnt 128 byte large, and also why decrypt function also requires a 128 byte array, is it some padding thing?

这就是我所谓的加密函数的方式:

This is how I call the encrypt function:

System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();  // encoding type
byte[] buff = new byte[128];     // this is my buffer array, instantiated and initiated
string String2Encrypt = "Testing";      // this is the string I need encrypted
byte[] tempo = encoding.GetBytes(String2Encrypt);   // getting bytes from string
Buffer.BlockCopy(tempo, 0, buff, 0, tempo.Length);    // copying the small array into the large one
uint inputlength = Convert.ToUInt32(tempo.Length);   // getting the size of the small array 


bool DidIt = UnsafeNativeMethods.CryptEncrypt(MyKey, IntPtr.Zero, 1, 0, buff, ref inputlength, outputdatalength);     // calling the function

//在这种情况下,MyKey是指向加密密钥的指针,第二个参数为null,第三个为"true"(没有更多数据),没有标志,缓冲字节数组(128),在这种情况下为Testing.Length是7、128

// in this case, the MyKey is pointer to a crypto key, 2nd argument is null, 3rd is "true" (no more data), no flags, buffer byte array (128), Testing.Length in this case it is 7, 128

这是我解密的方式:

IntPtr UserKeyLocal = MyUserKey;     // taking an argument (MyUserKey) and "filling" the local variable, not really relevant
byte[] dataCopy = new byte[buff.Length];   // init and insta the datacopy array (128 byte)
Buffer.BlockCopy(buff, 0, dataCopy, 0, (int)buff.Length);   // copying the argument array into a local version (I used this for testing to go around another problem), irrelevant
uint locinputlength = inputlength;  // another argument made local
bool DidIT = UnsafeNativeMethods.CryptDecrypt(UserKeyLocal, IntPtr.Zero, true, 0, dataCopy, ref locinputlength);     // calling the function

结果将如下所示: 测试R ???? 7?q ????? $ ?? uj ?? m%?b ?? e?a?74p?)?n9 ?? w?R * O)E?> [?S ???} Ct?n?& ?? b?P!?u1 ??%?JQ ???/?mP?5wB ????

The result would look like this: Testing?R????7?q?????$??uj??m%?b??e?a?74p?)?n9??w?R*O)E?i?+?>[?S???}Ct?n?&??b?P!?u1??%?JQ???/?mP?5wB????

它几乎可以按预期工作,但我只需要不使用子字符串之类的技巧就可以获取字符串的测试"部分.

Its almost working as intended but I need to be able to get ONLY the "Testing" part of the string without using tricks like substringing.

我正在尝试做的(也许有替代方法)是这样;我有一个二进制文件(文件),该文件中有一个测试",该文件由从我从智能卡导出的证书中获得的公共密钥加密. 我需要通过使用我的SmartCard(我正在使用其专有的CSP)和私钥来验证(解密)此文件.如您所见,它几乎可以正常工作.

What I am trying to do (maybe there is an alternative way) is this; I have a binary (file) that has in it "Testing" encrypted by a public key I got from a certificate which I exported form a SmartCard. I need to verify (decrypt) this file by using my SmartCard (I am using its propriety CSP) with the private key. As you can see, it ALMOST works.

提前谢谢.

推荐答案

我认为缓冲区必须为128字节的原因是使用了分组密码.在这种情况下,缓冲区长度必须是块大小的倍数.对于块密码,无论如何缓冲区都可能需要大于数据的大小,以便可以将加密或解密的数据写入其中(length(encrypted)!= length(plaintext)).

I think the reason the buffer must be 128 bytes is that a block cipher is being used. In that case, the buffer length must be a multiple of the block size. With a block ciper, the buffer may need to be larger than the size of the data anyway, so that the encrypted or decrypted data can be written to it (length(encrypted) != length(plaintext)).

调用CryptDecrypt之后,参数pdwDataLen(代码中的locInputLength)将包含已解密的实际数据的长度.如果仅使用dataCopy的前locInputLength个字节,它是否满足您的需求?

After you call CryptDecrypt, the parameter pdwDataLen (locInputLength in your code) will contain the length of the actual data that was decrypted. If you take only the first locInputLength bytes of dataCopy, does it give you what you need?

参考: http://msdn.microsoft.com/en-us/library/aa379913(VS.85).aspx http://msdn.microsoft.com/zh-CN/library/aa379924(VS.85).aspx

References: http://msdn.microsoft.com/en-us/library/aa379913(VS.85).aspx http://msdn.microsoft.com/en-us/library/aa379924(VS.85).aspx

这篇关于Pinvoking adwapi.dll-cryptDecrypt和cryptEncrypt函数,奇怪的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆