0

我正在观察此函数的奇怪行为,我要加密的字符串包含 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,第三个是“真”(没有更多数据),没有标志,缓冲区字节数组 (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

结果如下所示: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????

它几乎按预期工作,但我需要能够只获得字符串的“测试”部分,而不使用子字符串等技巧。

我正在尝试做的(也许有另一种方法)是这样的;我有一个二进制文件(文件),其中包含由我从智能卡导出的证书中获得的公钥加密的“测试”。我需要使用我的智能卡(我正在使用它的专有 CSP)和私钥来验证(解密)这个文件。如您所见,它几乎可以工作。

提前致谢。

4

2 回答 2

2

我认为缓冲区必须为 128 字节的原因是正在使用分组密码。在这种情况下,缓冲区长度必须是块大小的倍数。使用块密码,缓冲区可能需要大于数据的大小,以便可以将加密或解密的数据写入其中(长度(加密)!=长度(明文))。

调用 CryptDecrypt 后,参数pdwDataLenlocInputLength在您的代码中)将包含已解密的实际数据的长度。如果您只取 的第一个locInputLength字节dataCopy,它会满足您的需求吗?

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

于 2011-03-20T02:38:12.067 回答
0

是的,做到了!非常简单!

            byte[] buffer = new byte[locinputlength];
            Buffer.BlockCopy(dataCopy, 0, buffer, 0, (int)locinputlength);
            return buffer;

在您退后一点并从稍微不同的角度看待事物之前,您只是不会“看到”其中的一件事;)

于 2011-03-21T11:56:23.347 回答