使用SSL与Delphi,但仍然拥有单个exe文件

9
我们使用Indy,需要在我们的应用程序中支持SSL电子邮件,但是我们需要将应用程序放在单个.Exe文件中。
我们知道默认的Indy处理程序需要在路径中拥有dll。从其中一个EXE资源中提取Dlls将是最后的选择。
还有更好的建议吗?

你可能在谈论Indy使用的两个Open SSL DLL?你需要的是Delphi实现这些DLL所做的事情,我怀疑这是不可用的。 - J__
是的,我谈到过它们。但我不认为使用Delphi实现OpenSSL库是唯一的选择。无论如何,感谢澄清。 - John Thomas
8个回答

8

5

TOndrey给出了一个很好的答案,我也使用SecureBlackBox。

你可以考虑一些其他的第三方组件:


3
请注意:如果您在可执行文件中添加SSL/TLS支持,可能会导致其受出口限制。如果您在美国,这意味着您的应用程序不能销售或提供给美国以外的人。这就是为什么这些DLL不是Indy或Delphi本身的一部分的原因。
Delphi使用的库实际上是来自OpenSSL项目的编译后的DLL。但是,如果您具有良好的C知识,则应该能够将源代码编译为.obj文件,并将其与您的Delphi代码链接起来。您可能还需要修改Indy代码的某些部分。当然,其他人也可以这样做,但由于出口限制的存在,这使得这些Indy组件(甚至是Delphi本身)的出口更加复杂。
有趣的是,源代码受第一修正案保护,这基本上允许您将代码打印在书中,然后发送给某些流氓国家。但是,如果您以数字形式发送它(编译或未编译),那么您就会犯联邦罪行,并且可能需要至少一年小心地挑选淋浴时的肥皂... 没有人声称法律有意义。它们只能是一个[beep]的痛苦...
其他SSL解决方案与Indy组件不兼容,这意味着您必须重写部分代码才能支持那些其他解决方案。
此链接告诉您如何从内存中加载DLL,因此您无需将其放在磁盘上。这是一种我没有尝试过的备选方案。我认为它不会起作用,因为这两个DLL相互依赖,但值得一试...

除非他的计划是让客户单独下载DLL文件,否则他将受到出口限制的约束,因为他将一起分发程序和必需的DLL文件。 - Rob Kennedy
据我所知,一些出口限制已经被解除 - 例如现在Apache提供SSL启用的下载。 - user160694
出口限制主要是针对从美国出口,虽然其他国家也有类似的限制。忽视这个限制是自己承担风险,但我不认为风险很大。OpenSSL库包含相当多的加密技术,因此该库受到限制。Apache-SSL基于OpenSSL,但由英国机构托管,因此它们还受到其他限制。 - Wim ten Brink

2

“单个EXE”是用于分发目的还是在客户机上运行时也必须是单个.EXE文件?

如果仅用于分发目的,您可以将DLL文件附加到您的.EXE文件末尾,然后-当程序启动时-从.EXE文件中提取它们并将它们作为.DLL文件存储在本地,类似于这样:

VAR F,O : FILE;
VAR BUF : ARRAY[1..<MaxSizeOfDLLs>] OF BYTE;
ASSIGN(F,ParamStr(0)); RESET(F,1);
SEEK(F,<OriginalExeSize>);
BLOCKREAD(F,BUF,<FirstDllSize>);
ASSIGN(O,<NameOfFirstDLL>); REWRITE(O,1);
BLOCKWRITE(O,BUF,<FirstDllSize>); CLOSE(O);
BLOCKREAD(F,BUF,<SecondDllSize>);
ASSIGN(O,<NameOfSecondDLL>); REWRITE(O,1);
BLOCKWRITE(O,BUF,<SecondDllSize>); CLOSE(O);
SEEK(F,<OriginalExeSize>); TRUNCATE(F); CLOSE(F)

这只是一个快速而简单的程序,格式并不规范,但应该可以给你基本的概念。


1
一位经验丰富的COBOL程序员可以用任何语言编写COBOL程序。;-) - Ondrej Kelle
嵌入SSL代码可以增加拦截调用的难度。使用DLL时,有人可能会编写代理DLL并拦截调用。如果应用程序在受控环境(例如Web服务器)中运行,则这不是问题,但在不受控制的环境中可能存在风险。 - user160694

2
你尝试过自行编译OpenSSL源代码并将目标文件导入Delphi吗?
推荐阅读:在Delphi中使用C对象文件 - 解释了如何创建一个不需要DLL的程序,并且可以部署为一个整体。

Indy 10有一个IdSSLOpenSSLHeaders_static.pas单元,用于静态链接到OpenSSL。它仅适用于iOS,但如果您有适合的OBJ,则可以将其调整为在其他平台上运行。 - Remy Lebeau

1

我使用微软的CAPICOM来解决我的SSL3需求...它是免费可再分发的已经停止更新了。

如果你尝试其他组件,也许你应该看看SYNAPSE(位于http://synapse.ararat.cz/)(我也在使用),它可以与StreamSec(和其他组件)一起工作,以通过SSL发送电子邮件。它是免费且易于使用。


0

常量

  cdoSendUsingMethod = 'http://schemas.microsoft.com/cdo/configuration/sendusing';  
  cdoSMTPServer = 'http://schemas.microsoft.com/cdo/configuration/smtpserver';  
  cdoSMTPServerPort = 'http://schemas.microsoft.com/cdo/configuration/smtpserverport';  
  cdoSendServerPort = '25';  
  cdoSendUsingPort = 2;  
  cdoSMTPConnectionTimeout = 'http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout';  
  cdoSMTPAuthenticate = 'http://schemas.microsoft.com/cdo/configuration/smtpauthenticate';  
  cdoAnonymous = '0';  
  cdoBasic = '1';  
  cdoSMTPUseSSL = 'http://schemas.microsoft.com/cdo/configuration/smtpusessl';  
  cdoSendUserName = 'http://schemas.microsoft.com/cdo/configuration/sendusername';  
  cdoSendPassword = 'http://schemas.microsoft.com/cdo/configuration/sendpassword';  
  cdoURLGetLatestVersion = 'http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion';  

...

function SensCDOMail (ASubject, AFrom, ATo, ABody, ASmtpServer : WideString): String;  
var 

  cdoMessage:OleVariant;  
  cdoConfiguration: OleVariant;  

begin  

  //Configuration Object  
  cdoMessage:= CreateOleObject('CDO.Message');  
  cdoConfiguration:= CreateOleObject('CDO.Configuration');  
  try  

    cdoConfiguration.Fields(cdoSendUsingMethod):= cdoSendUsingPort;  
    cdoConfiguration.Fields(cdoSMTPServer):= ASmtpServer;  
    cdoConfiguration.Fields(cdoSMTPServerPort):= cdoSendServerPort;  
    cdoConfiguration.Fields(cdoSMTPAuthenticate):= cdoAnonymous;  
    cdoConfiguration.Fields(cdoSMTPUseSSL ):= True; // use SSL  
    cdoConfiguration.Fields.Update;  
    cdoMessage.Configuration:= cdoConfiguration;  
    cdoMessage.To       := ATo;
    cdoMessage.From     := AFrom;
    cdoMessage.Subject  := ASubject;
    //cdoMessage.HTMLBody := ABody;   //Want to send in Html format
    cdoMessage.TextBody := ABody;     //Want to send in text format
    cdoMessage.Send;

  finally  
    VarClear(cdoMessage);  
    VarClear(cdoConfiguration);  
  end;  
end;  


CDO需要在最终用户机器上安装各种DLL。如果安装了早期版本的Outlook,则这些文件会自动存在,但是微软停止在Outlook 2007及更高版本中安装CDO文件,因此提供了一个CDO的redist。 - J__

0

可以将这些DLL文件作为资源包含在程序的可执行文件中,使用时将其导出到文件中,甚至可以通过重新定位代码并在内存中搜索入口点而无需首先导出它们。我有一些代码可以实现后者...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接