无法使用 Delphi 从 Gmail 帐户 Download/Retrieve 发送电子邮件(SSL3_GET_RECORD:版本号错误)

Can't Download/Retrieve Email from Gmail account with Delphi (SSL3_GET_RECORD:wrong version number)

我无法 Download/Retrieve 使用 Delphi + Indy 从 Gmail 发送电子邮件!

几个星期以来,我无法阅读来自 Gmail 的电子邮件。

在下面的代码工作正常之前。

现在,我总是收到此错误消息:

error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong 版本号

正在连接到 Gmail。

Cryptosense Blog 我读

As trailed back in September 2015, Google are turning off SSLv3 and RC4 support from their TLS servers.

现在有什么解决方法可以从 Gmail 阅读电子邮件吗?

我的代码是这样的:

  1. 开始一个新的 Delphi 项目

  2. 您必须从该站点下载 SSL dll:

http://indy.fulgan.com/SSL/indy_OpenSSL096m.zip

  1. 解压缩文件并将 libeay32.dll 和 ssleay32.dll 放入您的项目路径。

  2. 用下面的代码替换Unit1.pas和Unit1.dfm的代码

  3. 更改 POP3 组件上的用户名和密码属性以匹配您的 GMAIL 帐户。

  4. 运行这

//开始代码

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdExplicitTLSClientServerBase, IdMessageClient, IdPOP3,
  IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL;

type
  TForm1 = class(TForm)
    POP3: TIdPOP3;
    Button1: TButton;
    SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  IdMessage, IdText;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  lMsg: TIdMessage;
  liCount: Integer;
  liMessages: Integer;
begin
  POP3.Connect;
  liMessages := POP3.CheckMessages;
  Memo1.Lines.Add('CheckMessages: ' + IntToSTr(liMessages));
  lMsg := TIdMessage.Create;
  try
    POP3.Retrieve(1, lMsg);
    Memo1.Lines.Text := lMsg.MsgId;
    for liCount := 0 to lMsg.MessageParts.Count-1 do
      if lMsg.MessageParts[liCount] is TIdText then
        Memo1.Lines.AddStrings((lMsg.MessageParts[liCount] as TIdText).Body);
  finally
    lMsg.Free;
  end;
end;

end.

//代码结束

//开始DFM

object Form1: TForm1
  Left = 192
  Top = 114
  Width = 696
  Height = 480
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 216
    Top = 16
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Memo1: TMemo
    Left = 24
    Top = 56
    Width = 657
    Height = 185
    Lines.Strings = (
      'Memo1')
    TabOrder = 1
  end
  object POP3: TIdPOP3
    IOHandler = SSLHandler
    AutoLogin = True
    Host = 'pop.gmail.com'
    Username = 'YourName@gmail.com'
    UseTLS = utUseImplicitTLS
    Password = 'YourPassword'
    Port = 995
    SASLMechanisms = <>
    Left = 40
    Top = 16
  end
  object SSLHandler: TIdSSLIOHandlerSocketOpenSSL
    Destination = 'pop.gmail.com:995'
    Host = 'pop.gmail.com'
    MaxLineAction = maException
    Port = 995
    DefaultPort = 0
    SSLOptions.Method = sslvSSLv3
    SSLOptions.Mode = sslmUnassigned
    SSLOptions.VerifyMode = []
    SSLOptions.VerifyDepth = 0
    Left = 80
    Top = 16
  end
end

//DFM结束

只需将 SSLOptions.MethodsslvSSLv3 更改为 sslvTLSv1

以下测试代码对我通过 POP3 登录 Gmail 工作正常:

procedure Test;
var
  IdPOP3: TIdPOP3;
  IdSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
  IdPOP3 := TIdPOP3.Create(nil);
  try
    IdPOP3.Host := 'pop.gmail.com';
    IdPOP3.Port := 995;
    IdPOP3.Username := MyGmailUsername;
    IdPOP3.Password := MyGmailAppPassword;
    IdPOP3.ConnectTimeout := 60000;

    IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdPOP3);
    IdSSL.SSLOptions.Method := sslvTLSv1;
    IdSSL.SSLOptions.Mode := sslmClient;
    IdPOP3.IOHandler := IdSSL;
    IdPOP3.UseTLS := utUseImplicitTLS;

    IdPOP3.Connect;
    try
      // use IdPOP3 as needed...
    finally
      IdPOP3.Disconnect;
    end;
  finally
    IdPOP3.Free;
  end;
end;

更新

注意:Indy 本身还不支持 OAuth 身份验证(但有 3rd 方实现浮动),所以如果你想使用你的真实密码(而不是使用 3rd 方身份验证),那么你需要调整你的Google 帐户安全设置更改为 allow less secure apps to access your account. However, if you have 2-Step Verification enabled in your account (and you should), you DO NOT need to allow access to "less secure apps", you can instead generate an application-specific password 并使用它代替您的真实密码。