Microsoft加密API禁用RSAES-OAEP密钥传输算法的使用


71

CryptEncryptMessage用来生成PKCS#7一封信封邮件。我正在使用szOID_NIST_AES256_CBC作为加密算法。

生成的消息似乎是有效的,但是它是RSAES-OAEP针对密钥传输算法的,它在野外的支持有限(Thunderbird,OpenSSL SMIME Module等不支持它)。

我希望CAPI恢复为旧版本RSAencryption以进行密钥传输。

有没有办法做到这一点,如果有办法而不是使用,我可以回复到低级消息传递功能 CryptEncryptMessage但是即使使用低级功能,我也找不到方法。

码:


1
欢迎来到stackoverflow!对于没有复杂的API知识的程序员来说,这是一个相当棘手的问题。也许您也可以尝试一些有关CAPI的资源。
Maarten Bodewes 2012年

11
该死,微软的加密API完全没有指定(通常)。
Maarten Bodewes,2012年

@owlstead,完全令人困惑。OP可能使用完全不同的路径来加密他的消息,这可以解决他的问题,但可以用10种不同的方法代替。
Adrian Ratnapala 2013年

1
出于使用RSA-OAEP的原因,请参阅Matthew Gree博士的博客密码令牌行业发展前景不佳。但是有人说我们是用我们知道的恶魔换来我们不知道的恶魔。
jww

4
客户端/服务器不必同意他们共享的算法吗?如果是这样,您可以从受支持的算法列表中删除不需要的任何内容。stackoverflow.com/a/4807830/1162141有一些很好的例子,你可以修改上下文关系中msdn.microsoft.com/en-us/library/windows/desktop/...
technosaurus

Answers:


2

密钥传输算法处理起来有些棘手,并且可能无法达到目的(我看到您指出您希望CAPI支持RSAencryption;也请相信我)。您似乎已经检测到大部分问题-生成的消息似乎有效,但是您的方法需要使用CryptEncryptMessage,从长远来看,它不会很好/根本不会起作用。

第1步-检查代码

很基本,不是吗?虽然有效,但并不能真正解决问题。如果你看这个:

您会看到它是预定义的,但仅用于 retval。但是,我可以肯定地将其视为微优化,如果我们要重新编写代码,它并不是真正有用的。但是,我概述了在不完全重做代码的情况下集成此功能的基本步骤(因此您可以继续使用相同的参数):

第2步-编辑参数

正如@owlstead在他的评论中提到的那样,Crypto API不是非常用户友好的。但是,您在资源有限的情况下做得很好。您想要添加的是一个加密枚举提供程序,以帮助缩小密钥范围。请确保您具有Microsoft基本加密提供程序版本1.0或Microsoft增强加密提供程序版本1.0,以有效地使用它们。否则,您需要像这样添加函数:

这主要用于防止NTE_BAD_FLAGS错误,尽管从技术上讲,您可以使用更底层的声明来避免这种情况。如果需要,您还可以创建一个全新的哈希(尽管只有在上述实现无法扩展到必要的时间/速度因数的情况下才有必要):

在继续操作之前,请确保为该代码片段添加安全性。您可以轻松地这样做:

如果您要记录或发布文档,则可能要添加一个 void MyHandleError(char *s)以捕获错误,以便编辑但失败的人员可以快速捕获该错误。

顺便说一句,因为没有默认值,所以第一次运行它时,您必须创建一个新集。if下面是一个可以弹出的不错的单线:

请记住,同步服务器资源会 被视为有效的做重新工作,我在第一个步骤建议。这是我将在下面解释的内容:

步骤3-重新编码并重新启动

作为程序员,重新编码可能看起来很浪费时间,但是从长远来看,它绝对可以帮助您。请记住,编码/同步时仍然需要在自定义参数中进行编码;我不会像婴儿一样用手喂所有代码。足以向您展示基本轮廓。

我绝对假设您正在尝试处理特定CSP中当前用户的密钥容器;否则,我不会真正看到此用法。如果没有,您可以进行一些基本的编辑以满足您的需要。

记住,我们将CryptEncryptMessage通过使用绕过CryptReleaseContext,它直接释放该CryptAcquireContext函数获取的句柄。Microsoft在CAC上的标准如下:

请注意,如果您使用的是用户界面,Microsoft会责骂您:

如果CSP必须显示UI才能运行,则调用将失败,并且NTE_SILENT_CONTEXT错误代码被设置为最后一个错误。此外,如果使用带有CRYPT_USER_PROTECTED标志的CryptGenKey进行调用,并且已使用CRYPT_SILENT标志获取了上下文,则调用将失败,并且CSP将设置NTE_SILENT_CONTEXT。

这主要是服务器代码,ERROR_BUSY当存在多个连接(尤其是那些具有高延迟的连接)时,肯定会向新用户显示。NTE_BAD_KEYSET_PARAM由于超时,超过300ms只会导致调用a或类似名称,甚至没有收到适当的错误。(传输问题,有人陪我吗?)

除非您担心多个DLL(由于NTE_PROVIDER_DLL_FAIL错误而不支持),否则获取客户端加密服务的基本设置如下(直接从Microsoft的示例复制):

无论它看起来多么简单,您都绝对不希望将其传递给密钥交换算法(或您要处理的其他任何事物)。除非您使用对称会话密钥(Diffie-Hellman / KEA),否则交换密钥对可用于加密会话密钥,以便可以安全地存储它们并与其他用户交换。

名为John Howard的人编写了一个不错的Hyper-V远程管理配置实用程序(HVRemote),该实用程序是此处讨论的技术的大型汇编。除了使用基本的crypt和keypair,它们还可用于允许ANONYMOUS LOGON远程DCOM访问(cscript hvremote.wsf具体来说,)。您可以在他的博客上看到他最新的加密技术中的许多功能和技术(您必须缩小查询范围):

http://blogs.technet.com/b/jhoward/

如果您需要更多基础知识帮助,请发表评论或请求私人聊天。

结论

尽管一旦实现了哈希的基本服务器端方法以及客户端如何获取“加密”,这很简单,但您会质疑为什么在传输过程中甚至尝试加密。但是,如果没有加密客户端,则加密绝对是传输已散列数据的唯一安全方法。

尽管您可能会争辩说可以对数据包进行解密并从盐中散列出来,但是请考虑必须按照正确的时序顺序处理和存储两个入站以重新哈希客户端。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.