我有一个用C++ for Windows编写的现有应用程序.此应用程序使用Win32 CryptoAPI生成用于加密/解密数据的TripleDES会话密钥.我们使用一个技巧的指数将会话密钥导出为blob,这允许blob以解密格式存储在某处.
问题是我们如何在.NET应用程序(C#)中使用它.该框架封装/包装了CryptoAPI正在做的大部分内容.部分问题是CryptAPI声明Microsoft增强加密提供程序的TripleDES算法是168位(56位的3个密钥).但是,.NET框架声明它们的密钥是192位(64位的3个密钥).显然,.NET框架中的3个额外字节用于奇偶校验?
无论如何,我们需要从blob中读取关键部分,并以某种方式能够在我们的.NET应用程序中使用它.目前,我们在尝试在.NET中使用密钥时没有得到预期的结果.解密失败了.任何帮助将不胜感激.
我一直在努力解决这个问题,并提出了一个我将及时发布的解决方案.但是,仍然会感谢来自其他人的任何反馈.
我终于开始发布解决方案了.我希望它能为那些可能做类似事情的人提供一些帮助.在其他地方真的没有太多的参考.
为了使其中的许多内容有意义,有必要读取一个技巧的指数,这允许您将会话密钥导出到blob(一个众所周知的字节结构).然后可以用这个字节流做他们想做的事情,但它拥有所有重要的键.
在此特定示例中,我使用Microsoft增强加密提供程序,使用Triple DES(CALG_3DES)算法.抛弃循环的第一件事是密钥长度以168位列出,块长度为64位.钥匙长度怎么样168?56位的三个键?另一个字节会发生什么?
因此,有了这些信息,我开始在其他地方读取最后一个字节是如何真正的奇偶校验,无论出于何种原因,CryptoAPI将其剥离.那是真的吗?看起来有点疯狂,他们会这样做,但好吧.
使用TripleDESCryptoServiceProvider,我注意到文档中的备注表明:
该算法支持从128位到192位的密钥长度,增量为64位.
因此,如果CryptoAPI的密钥长度为168,我将如何将其转换为支持仅支持64的倍数的.NET?因此,API的.NET端需要考虑奇偶校验,而CryptoAPI则不考虑.可以想象...... 我很困惑.
所有这些,我试图弄清楚如何使用适当的奇偶校验信息重建.NET端的密钥.可行,但不是很有趣......让我们离开吧.一旦我完成所有这些,一切都以CAPITAL F失败了.
还在我这儿?好,因为我刚从马上掉下来.
低,看,因为我正在抓取MSDN的最后一点信息,我发现在Win32 CryptExportKey函数中有一个冲突的部分.很低,我发现这条非常宝贵的信息:
对于使用PLAINTEXTKEYBLOB的任何DES密钥排列,只能导出包括奇偶校验位的完整密钥大小.支持以下密钥大小.
算法支持的密钥大小
CALG_DES 64位
CALG_3DES_112 128位
CALG_3DES 192位
所以它确实导出一个64位倍数的密钥!哇噢!现在修复.NET端的代码.
在导入包含从CryptoAPI导出为blob的密钥的字节流时,记住字节顺序非常重要.这两个API不使用相同的字节顺序,因此,正如@ nic-strong所示,在实际尝试使用密钥之前,反转字节数组是必不可少的.除此之外,事情按预期工作.简单解决:
Array.Reverse( keyByteArray );
我希望这有助于那里的人.我花了太多时间试图追踪这一点.如果您有其他问题,请留下任何评论,我可以尝试帮助填写任何详细信息.
快乐的加密!