我正在观察这个函数的奇怪行为,我要加密的字符串包含14个字节,如果我使用函数发送缓冲区的长度= 14,则失败(“内部错误” - 非常具有描述性和最有帮助错误代码),但它在缓冲区长度(和缓冲区本身)大128字节时有效。
我通过制作128字节大小的数组克服了这个问题,并从纯文本中复制了14个字节(我希望加密),
当我解密那些字节时,我必须再次给该函数提供整个128字节数组(现在每个字节都加密,甚至是#13-#127(我想是可以预料的))。幸运的是,对我来说,前14个字节应该得到解密,剩下的就是胡言乱语。
我想知道为什么如果传入的缓冲区不是128字节大,加密方法会失败,为什么解密函数也需要一个128字节的数组,这是一些填充的东西吗?
这就是我调用加密函数的方法:
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,3rd是“true”(没有更多数据),没有标志,缓冲区字节数组(128),在这种情况下是Testing.Length它是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 ??米%3 B 48 E'一?74P?)?N9 ??瓦特?R * O)E'{{1} }> [Sαδ+}的Ct N'安培;??14 b P U1 ??%JQ ??? / MP 5wB ????
?!????它几乎按预期工作但我需要能够只使用字符串的“测试”部分而不使用像子串一样的技巧。
我想做的事(也许有另一种方法)是这样的;我有一个二进制(文件),其中包含“测试”,这是我从我从智能卡导出的证书中获得的公钥加密的。 我需要使用我的智能卡(我使用其专有CSP)和私钥来验证(解密)此文件。如您所见,它几乎可以工作。
提前致谢。
答案 0 :(得分:2)
我认为缓冲区必须是128字节的原因是正在使用块密码。在这种情况下,缓冲区长度必须是块大小的倍数。使用块ciper,缓冲区可能需要大于数据的大小,以便加密或解密的数据可以写入它(长度(加密)!= length(明文))。
调用CryptDecrypt后,参数pdwDataLen
(代码中的locInputLength
)将包含已解密的实际数据的长度。如果您只选择locInputLength
的前dataCopy
个字节,它会为您提供所需内容吗?
参考文献: http://msdn.microsoft.com/en-us/library/aa379913(VS.85).aspx http://msdn.microsoft.com/en-us/library/aa379924(VS.85)的.aspx
答案 1 :(得分:0)
byte[] buffer = new byte[locinputlength];
Buffer.BlockCopy(dataCopy, 0, buffer, 0, (int)locinputlength);
return buffer;
你直接退后一步,从一个略微不同的角度看待事物之前你不会“看到”的其中一件事;)