SSL连接建立过程分析

1. 应用程序接口
1.1 SSL初始化
SSL_CTX* InitSSL(int server, char *cert, char *key, char *pw)
{
    SSL_CTX* ctx;
    SSL_METHOD *meth;
    int status;
// 算法初始化   
// 加载SSL错误信息
    SSL_load_error_strings();
// 添加SSL的加密/HASH算法
    SSLeay_add_ssl_algorithms();
// 服务器还是客户端
    If(server)
 meth = SSLv23_server_method();
    else
 meth = SSLv23_client_method();
// 建立新的SSL上下文
    ctx = SSL_CTX_new (meth);
    if(!ctx) return NULL;
// 设置证书文件的口令
    SSL_CTX_set_default_passwd_cb_userdata(ctx, pw);
//加载本地证书文件
    status=SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_ASN1);
    if (status <= 0) {
        frintf(stderr, "Use cert fail, status=%d\n", status);
        goto bad;
    }
// 加载私钥文件
    if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) <= 0) {
        fprintf(stderr, "Use private key fail\n");
        goto bad;
    }
// 检查证书和私钥是否匹配
    if (!SSL_CTX_check_private_key(ctx)) {
        fprintf("Private key does not match the certificate public key\n");
        goto bad;
    }
    fprintf("Cert and key OK\n");
    return ctx;
bad:
    SSL_CTX_free (ctx);
    return NULL;
}
1.2 建立SSL新连接
服务器:
// 建立SSL
ssl = SSL_new (ctx);
// 将SSL与TCP socket连接
SSL_set_fd (ssl, sd);
//接受新SSL连接
err = SSL_accept (ssl);
客户端:
// 建立SSL
ssl = SSL_new (ctx);
// 将SSL与TCP socket连接
SSL_set_fd (ssl, sd);
// SSL连接
err = SSL_connect (ssl);


服务器的SSL_accept()和客户端的SSL_connect()函数共同完成SSL的握手协商过程。
 
1.3 SSL通信
和普通的read()/write()调用一样,用下面的函数完成数据的SSL发送和接收,函数输入数据是明文,SSL自动将数据封装进SSL中:
读/接收:SSL_read()
写/发送:SSL_write()
1.4 SSL释放
SSL释放很简单:
 SSL_free (ssl);
 
2. SSL实现分析
以下SSL源代码取自openssl-0.9.7b。


2.1 SSL_load_error_strings
该函数加载错误字符串信息:
void SSL_load_error_strings(void)
 {
#ifndef OPENSSL_NO_ERR
 ERR_load_crypto_strings();
 ERR_load_SSL_strings();
#endif
 }
最后将会进入函数:
static void err_load_strings(int lib, ERR_STRING_DATA *str)
 {
 while (str->error)
  {
  str->error|=ERR_PACK(lib,0,0);
  ERRFN(err_set_item)(str);
  str++;
  }
 }
其中:
#define ERR_PACK(l,f,r)  (((((unsigned long)l)&0xffL)*0x1000000)| \
    ((((unsigned long)f)&0xfffL)*0x1000)| \
    ((((unsigned long)r)&0xfffL)))
#define ERRFN(a) err_fns->cb_##a
ERRFN(err_set_item)(str)的实际函数实现为:
static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
 {
 ERR_STRING_DATA *p;
 LHASH *hash;
 err_fns_check();
 hash = ERRFN(err_get)(1);
 if (!hash)
  return NULL;
 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
 p = (ERR_STRING_DATA *)lh_insert(hash, d);
 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
 return p;
 }
Lh_insert()将错误信息插入到一个链表中
如关于加密算法的错误信息:
/* crypto/err/err.c */
static ERR_STRING_DATA ERR_str_functs[]=
……
static ERR_STRING_DATA ERR_str_libraries[]=
……
static ERR_STRING_DATA ERR_str_reasons[]=
……
 
2.2 SSLeay_add_ssl_algorithms()
这实际是个宏:
#define OpenSSL_add_ssl_algorithms()    SSL_library_init()
#define SSLeay_add_ssl_algorithms() SSL_library_init()
实际函数为SSL_library_init(),函数比较简单,就是加载各种加密和HASH算法:
/* ssl/ssl_algs.c */
int SSL_library_init(void)
 {
#ifndef OPENSSL_NO_DES
 EVP_add_cipher(EVP_des_cbc());
 EVP_add_cipher(EVP_des_ede3_cbc());
#endif
#ifndef OPENSSL_NO_IDEA
 EVP_add_cipher(EVP_idea_cbc());
#endif
#ifndef OPENSSL_NO_RC4
 EVP_add_cipher(EVP_rc4());
#endif  
#ifndef OPENSSL_NO_RC2
 EVP_add_cipher(EVP_rc2_cbc());
#endif
#ifndef OPENSSL_NO_AES
 EVP_add_cipher(EVP_aes_128_cbc());
 EVP_add_cipher(EVP_aes_192_cbc());
 EVP_add_cipher(EVP_aes_256_cbc());
#endif
#ifndef OPENSSL_NO_MD2
 EVP_add_digest(EVP_md2());
#endif
#ifndef OPENSSL_NO_MD5
 EVP_add_digest(EVP_md5());
 EVP_add_digest_alias(SN_md5,"ssl2-md5");
 EVP_add_digest_alias(SN_md5,"ssl3-md5");
#endif
#ifndef OPENSSL_NO_SHA
 EVP_add_digest(EVP_sha1()); /* RSA with sha1 */
 EVP_add_digest_alias(SN_sha1,"ssl3-sha1");
 EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);
#endif
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA)
 EVP_add_digest(EVP_dss1()); /* DSA with sha1 */
 EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2);
 EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1");
 EVP_add_digest_alias(SN_dsaWithSHA1,"dss1");
#endif
 /* If you want support for phased out ciphers, add the following */
#if 0
 EVP_add_digest(EVP_sha());
 EVP_add_digest(EVP_dss());
#endif
 return(1);
 }


2.3 SSL23_server_method()
建立服务器端的方法库,这是个通用函数,可动态选择SSL协议。如果想固定协议,可以只用SSLv2_server_method(), SSLv3_server_method() 等函数来初始化,该函数返回一个SSL_METHOD结构:
/* ssl/ssl.h */
/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
typedef struct ssl_method_st
 {
 int version; // 版本号
 int (*ssl_new)(SSL *s); // 建立新SSL
 void (*ssl_clear)(SSL *s); // 清除SSL
 void (*ssl_free)(SSL *s);  // 释放SSL
 int (*ssl_accept)(SSL *s); // 服务器接受SSL连接
 int (*ssl_connect)(SSL *s); // 客户端的SSL连接
 int (*ssl_read)(SSL *s,void *buf,int len); // SSL读
 int (*ssl_peek)(SSL *s,void *buf,int len); // SSL查看数据
 int (*ssl_write)(SSL *s,const void *buf,int len); // SSL写
 int (*ssl_shutdown)(SSL *s); // SSL半关闭
 int (*ssl_renegotiate)(SSL *s); // SSL重协商
 int (*ssl_renegotiate_check)(SSL *s); // SSL重协商检查
 long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg); // SSL控制
 long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg); //SSL上下文控制
 SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr); // 通过名称获取SSL的算法
 int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr); 
 int (*ssl_pending)(SSL *s); 
 int (*num_ciphers)(void); // 算法数
 SSL_CIPHER *(*get_cipher)(unsigned ncipher); // 获取算法
 struct ssl_method_st *(*get_ssl_method)(int version);
 long (*get_timeout)(void); // 超时
 struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ // SSL3加密
 int (*ssl_version)(); // SSL版本
 long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)()); // SSL控制回调函数
 long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)()); //SSL上下文控制回调函数
 } SSL_METHOD;


/* ssl/s23_srvr.c */
SSL_METHOD *SSLv23_server_method(void)
 {
 static int init=1;
// 静态量,每个进程只初始化一次
 static SSL_METHOD SSLv23_server_data;
 if (init)
  {
  CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
  if (init)
   {
// ssl23的基本方法结构
   memcpy((char *)&SSLv23_server_data,
    (char *)sslv23_base_method(),sizeof(SSL_METHOD));
// 服务器,所以要定义accept方法
   SSLv23_server_data.ssl_accept=ssl23_accept;
// 根据SSL的版本设置SSL的具体方法函数
   SSLv23_server_data.get_ssl_method=ssl23_get_server_method;
   init=0;
   }
  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
  }
 return(&SSLv23_server_data);
 }


static SSL_METHOD *ssl23_get_server_method(int ver)
 {
#ifndef OPENSSL_NO_SSL2
 if (ver == SSL2_VERSION)
  return(SSLv2_server_method());
#endif
 if (ver == SSL3_VERSION)
  return(SSLv3_server_method());
 else if (ver == TLS1_VERSION)
  return(TLSv1_server_method());
// 随着TLS1.1(RFC4346)的推出,估计不久将出现TLSv1_1_server_method()
 else
  return(NULL);
 }
// SSL23的方法基本数据定义
/* ssl/s23_lib.c */
SSL_METHOD *sslv23_base_method(void)
 {
 return(&SSLv23_data);
 }
static SSL_METHOD SSLv23_data= {
 TLS1_VERSION,
 tls1_new,
 tls1_clear,
 tls1_free,
 ssl_undefined_function,
 ssl_undefined_function,
 ssl23_read,
 ssl23_peek,
 ssl23_write,
 ssl_undefined_function,
 ssl_undefined_function,
 ssl_ok,
 ssl3_ctrl,
 ssl3_ctx_ctrl,
 ssl23_get_cipher_by_char,
 ssl23_put_cipher_by_char,
 ssl_undefined_function,
 ssl23_num_ciphers,
 ssl23_get_cipher,
 ssl_bad_method,
 ssl23_default_timeout,
 &ssl3_undef_enc_method,
 ssl_undefined_function,
 ssl3_callback_ctrl,
 ssl3_ctx_callback_ctrl,
 };
以SSL3的服务器方法函数为例,其他方法类似:
/* ssl/s3_srvr.c */
SSL_METHOD *SSLv3_server_method(void)
 {
 static int init=1;
 static SSL_METHOD SSLv3_server_data;
// 只初始化一次
 if (init)
  {
  CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
  if (init)
   {
// ssl3的基本方法结构
   memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(),
    sizeof(SSL_METHOD));
// ssl3的接受方法
   SSLv3_server_data.ssl_accept=ssl3_accept;
// ssl3获取服务器的方法函数
   SSLv3_server_data.get_ssl_method=ssl3_get_server_method;
   init=0;
   }
   
  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
  }
 return(&SSLv3_server_data);
 }
// SSL3的方法基本数据定义
/* ssl/s3_lib.c */
static SSL_METHOD SSLv3_data= {
 SSL3_VERSION,
 ssl3_new,
 ssl3_clear,
 ssl3_free,
 ssl_undefined_function,
 ssl_undefined_function,
 ssl3_read,
 ssl3_peek,
 ssl3_write,
 ssl3_shutdown,
 ssl3_renegotiate,
 ssl3_renegotiate_check,
 ssl3_ctrl,
 ssl3_ctx_ctrl,
 ssl3_get_cipher_by_char,
 ssl3_put_cipher_by_char,
 ssl3_pending,
 ssl3_num_ciphers,
 ssl3_get_cipher,
 ssl_bad_method,
 ssl3_default_timeout,
 &SSLv3_enc_data,
 ssl_undefined_function,
 ssl3_callback_ctrl,
 ssl3_ctx_callback_ctrl,
 };
 
2.4 SSL23_client_method()


和服务器端的其实是相同的,只是不定义结构中的ssl_accept而是定义ssl_connnect:
SSL_METHOD *SSLv23_client_method(void)
 {
 static int init=1;
 static SSL_METHOD SSLv23_client_data;
 if (init)
  {
  CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
  if (init)
   {
   memcpy((char *)&SSLv23_client_data,
    (char *)sslv23_base_method(),sizeof(SSL_METHOD));
   SSLv23_client_data.ssl_connect=ssl23_connect;
   SSLv23_client_data.get_ssl_method=ssl23_get_client_method;
   init=0;
   }
  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
  }
 return(&SSLv23_client_data);
 }
 
2.5 SSL_CTX_new ()
该函数根据SSL方法获取一个SSL上下文结构,该结构定义为:
/* ssl/ssl.h */
struct ssl_ctx_st
 {
 SSL_METHOD *method;
 STACK_OF(SSL_CIPHER) *cipher_list;
 /* same as above but sorted for lookup */
 STACK_OF(SSL_CIPHER) *cipher_list_by_id;
 struct x509_store_st /* X509_STORE */ *cert_store;
 struct lhash_st /* LHASH */ *sessions; /* a set of SSL_SESSIONs */
 /* Most session-ids that will be cached, default is
  * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */
 unsigned long session_cache_size;
 struct ssl_session_st *session_cache_head;
 struct ssl_session_st *session_cache_tail;
 /* This can have one of 2 values, ored together,
  * SSL_SESS_CACHE_CLIENT,
  * SSL_SESS_CACHE_SERVER,
  * Default is SSL_SESSION_CACHE_SERVER, which means only
  * SSL_accept which cache SSL_SESSIONS. */
 int session_cache_mode;
 /* If timeout is not 0, it is the default timeout value set
  * when SSL_new() is called.  This has been put in to make
  * life easier to set things up */
 long session_timeout;
 /* If this callback is not null, it will be called each
  * time a session id is added to the cache.  If this function
  * returns 1, it means that the callback will do a
  * SSL_SESSION_free() when it has finished using it.  Otherwise,
  * on 0, it means the callback has finished with it.
  * If remove_session_cb is not null, it will be called when
  * a session-id is removed from the cache.  After the call,
  * OpenSSL will SSL_SESSION_free() it. */
 int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess);
 void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess);
 SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl,
  unsigned char *data,int len,int *copy);
 struct
  {
  int sess_connect; /* SSL new conn - started */
  int sess_connect_renegotiate;/* SSL reneg - requested */
  int sess_connect_good; /* SSL new conne/reneg - finished */
  int sess_accept; /* SSL new accept - started */
  int sess_accept_renegotiate;/* SSL reneg - requested */
  int sess_accept_good; /* SSL accept/reneg - finished */
  int sess_miss;  /* session lookup misses  */
  int sess_timeout; /* reuse attempt on timeouted session */
  int sess_cache_full; /* session removed due to full cache */
  int sess_hit;  /* session reuse actually done */
  int sess_cb_hit; /* session-id that was not
      * in the cache was
      * passed back via the callback.  This
      * indicates that the application is
      * supplying session-id's from other
      * processes - spooky :-) */
  } stats;
 int references;
 /* if defined, these override the X509_verify_cert() calls */
 int (*app_verify_callback)(X509_STORE_CTX *, void *);
 void *app_verify_arg;
 /* before OpenSSL 0.9.7, 'app_verify_arg' was ignored
  * ('app_verify_callback' was called with just one argument) */
 /* Default password callback. */
 pem_password_cb *default_passwd_callback;
 /* Default password callback user data. */
 void *default_passwd_callback_userdata;
 /* get client cert callback */
 int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
 CRYPTO_EX_DATA ex_data;
 const EVP_MD *rsa_md5;/* For SSLv2 - name is 'ssl2-md5' */
 const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */
 const EVP_MD *sha1;   /* For SSLv3/TLSv1 'ssl3->sha1' */
 STACK_OF(X509) *extra_certs;
 STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */


 /* Default values used when no per-SSL value is defined follow */
 void (*info_callback)(const SSL *ssl,int type,int val); /* used if SSL's info_callback is NULL */
 /* what we put in client cert requests */
 STACK_OF(X509_NAME) *client_CA;


 /* Default values to use in SSL structures follow (these are copied by SSL_new) */
 unsigned long options;
 unsigned long mode;
 long max_cert_list;
 struct cert_st /* CERT */ *cert;
 int read_ahead;
 /* callback that allows applications to peek at protocol messages */
 void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
 void *msg_callback_arg;
 int verify_mode;
 int verify_depth;
 unsigned int sid_ctx_length;
 unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
 int (*default_verify_callback)(int ok,X509_STORE_CTX *ctx); /* called 'verify_callback' in the SSL */
 /* Default generate session ID callback. */
 GEN_SESSION_CB generate_session_id;
 int purpose;  /* Purpose setting */
 int trust;  /* Trust setting */
 int quiet_shutdown;
 };


typedef struct ssl_ctx_st SSL_CTX;
/* ssl/ssl_lib.h */
SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
 {
 SSL_CTX *ret=NULL;
 
 if (meth == NULL)
  {
  SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_NULL_SSL_METHOD_PASSED);
  return(NULL);
  }
 if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)
  {
  SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
  goto err;
  }
// 分配上下文的内存空间
 ret=(SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
 if (ret == NULL)
  goto err;
 memset(ret,0,sizeof(SSL_CTX));
 
// 初始化上下文的结构参数
 ret->method=meth;
 ret->cert_store=NULL;
 ret->session_cache_mode=SSL_SESS_CACHE_SERVER;
 ret->session_cache_size=SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
 ret->session_cache_head=NULL;
 ret->session_cache_tail=NULL;
 /* We take the system default */
 ret->session_timeout=meth->get_timeout();
 ret->new_session_cb=0;
 ret->remove_session_cb=0;
 ret->get_session_cb=0;
 ret->generate_session_id=0;
 memset((char *)&ret->stats,0,sizeof(ret->stats));
 ret->references=1;
 ret->quiet_shutdown=0;
/* ret->cipher=NULL;*/
/* ret->s2->challenge=NULL;
 ret->master_key=NULL;
 ret->key_arg=NULL;
 ret->s2->conn_id=NULL; */
 ret->info_callback=NULL;
 ret->app_verify_callback=0;
 ret->app_verify_arg=NULL;
 ret->max_cert_list=SSL_MAX_CERT_LIST_DEFAULT;
 ret->read_ahead=0;
 ret->msg_callback=0;
 ret->msg_callback_arg=NULL;
 ret->verify_mode=SSL_VERIFY_NONE;
 ret->verify_depth=-1; /* Don't impose a limit (but x509_lu.c does) */
 ret->sid_ctx_length=0;
 ret->default_verify_callback=NULL;
 if ((ret->cert=ssl_cert_new()) == NULL)
  goto err;
 ret->default_passwd_callback=0;
 ret->default_passwd_callback_userdata=NULL;
 ret->client_cert_cb=0;
 ret->sessions=lh_new(LHASH_HASH_FN(SSL_SESSION_hash),
   LHASH_COMP_FN(SSL_SESSION_cmp));
 if (ret->sessions == NULL) goto err;
 ret->cert_store=X509_STORE_new();
 if (ret->cert_store == NULL) goto err;
 
// 建立加密算法链表
 ssl_create_cipher_list(ret->method,
  &ret->cipher_list,&ret->cipher_list_by_id,
  SSL_DEFAULT_CIPHER_LIST);
 if (ret->cipher_list == NULL
     || sk_SSL_CIPHER_num(ret->cipher_list) <= 0)
  {
  SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_LIBRARY_HAS_NO_CIPHERS);
  goto err2;
  }
 
// 定义上下文结构中HASH算法
 if ((ret->rsa_md5=EVP_get_digestbyname("ssl2-md5")) == NULL)
  {
  SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES);
  goto err2;
  }
 if ((ret->md5=EVP_get_digestbyname("ssl3-md5")) == NULL)
  {
  SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES);
  goto err2;
  }
 if ((ret->sha1=EVP_get_digestbyname("ssl3-sha1")) == NULL)
  {
  SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES);
  goto err2;
  }
 if ((ret->client_CA=sk_X509_NAME_new_null()) == NULL)
  goto err;
 
 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);
 ret->extra_certs=NULL;
// 压缩算法
 ret->comp_methods=SSL_COMP_get_compression_methods();
 return(ret);
err:
 SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE);
err2:
 if (ret != NULL) SSL_CTX_free(ret);
 return(NULL);
 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
147 第四章 网络安全协议 1 第四章 网络安全协议 SSL协议 SET协议 IPSec协议 2 因特网与TCP/IP安全-1TCP/IP协议栈 TCP/IP是一组通信协议的缩写 ISO/OSI模型及其与TCP/IP的关系 3 因特网与TCP/IP安全-IP协议 IP数据包中含有源地址和目的地址 不可靠协议,没有做任何事情来确认数据包是否按顺序或是未被破坏 而高层在接受服务时通常假设源地址是有效的 IP地址成为认证的基础 IP协议存在的安全问题不少 4 IP欺骗 攻击者通过伪造一个可信任地址的数据包以使一台机器认证另一台机器的复杂技术 攻击是利用应用程序之间基于IP地址的认证机制,攻击者通过IP地址欺骗获得远程系统的非法授权访问。 5 IP欺骗 过程描述: 1、X->B: SYN(序列号为M),IP=A 2、B->A: SYN(序列号为N),ACK(应答序号=M+1) 此时A没有同B发起连接,当A收到B的包后,会发送RST置位的包给B,从而断开连接 此时攻击者事先让A无法对来自B的任何数据包进行应答。 3、X->B: ACK(应答序号=N+1) IP=A 攻击者猜测B发送给A的序列号。若猜测成功则,X将获得主机B赋予A的权利。 6 IP欺骗 辅助技术1:如何阻止A响应B的包- SYN 淹没 7 IP欺骗 辅助技术2:序列号预测 攻击者事先要进行连接试验: (1)同目标主机进行连接 (2)目标主机应答 (3)记录应答包所含的序列号,继续步骤1测试 分析序列号产生的模式 8 攻击检测 上述攻击过程中,攻击者必须依照一定的顺序来完成网络入侵,这往往是攻击的一种先兆。可安装一个网络嗅探器。 (1)最初,会检测到大量的TCP SYN从某个主机发往A的登录端口。 (2)大量的TCP SYN包将从主机X经过网络发往主机B,相应的有SYN+ACK包从主机B发往X,然后主机X用RST作应答 9 其他措施 配置路由器和网关,使他们拒绝网络外部与本网内具有相同IP地址的连接请求 当包的源IP地址不在本地子网内时,路由器和网关不应该把本网主机的包发出去,以阻止内部用户去破坏他人网络 10 因特网与TCP/IP安全-TCP协议 TCP安全缺陷-TCP连接的可靠性 初始化连接:三次握手,确保双方做好传输准备,统一序列号。 SYN, SEQ = x 主机 B SYN, ACK, SEQ = y, ACK= x 1 ACK, SEQ = x + 1, ACK = y 1 确认 确认 主机 A 连接请求 11 TCP安全缺陷-没有任何认证机制 TCP会话劫持 所谓会话,就是两台主机之间的一次通讯。 例如Telnet到某台主机,这就是一次Telnet会话; 浏览某个网站,这就是一次HTTP会话。 12 会话劫持(Session Hijack),就是在一次正常的会话过程当中,攻击者作为第三方参与到其中,他可以在正常数据包中插入恶意数据,也可以在双方的会话当中进行监听,甚至可以是代替某一方主机接管会话。 原因: TCP假定只要接受到的数据包含有正确的序列号就认为数据是可以接受的。 一旦连接建立,服务器无法确定进入的数据包是否来自真实的机器。 13 会话劫持防范 防范会话劫持是一个比较大的工程。 最根本的解决办法是采用加密通讯,使用SSH代替Telnet、使用SSL加强HTTP,或者干脆使用IPSec/VPN。 其次,监视网络流量,如发现网络中出现大量的ACK包,则有可能已被进行了会话劫持攻击。 完善认证措施,不仅仅在建立会话时进行认证 14 SSL协议—1 概况 SSL协议(Security Socket Layer)是Netscape公司于1994年提出的基于web应用的安全协议。主要介绍SSLv3. SSL主要采用公开密钥体制和x.509数字证书技术。 15 16 SSL协议—1 概况 协议的位置: SSL介于TCP和应用层协议之间。 SSL可以用于任何面向连接的安全通信,但通常用于安全web应用的HTTP协议。 SMTP IP SSL TCP HTTP FTP 17 SSL协议—1 概况 SSL提供一个安全的"握手"来初始化一个TCP/IP连接 建立TCP"连接" SSL握手,建立SSL会话 完成客户端和服务器之间关于安全等级、密码算法、通信密钥的协商,以及执行对连接端身份的认证工作。 SSL连接上所传送的应用层协议数据都会被加密,从而保证通信的机密性。 18 SSL协议—1 概况 提供的安全保护 SSL 服务器鉴别 允许用户证实服务器的身份。具有 SS L功能的浏览器维持一个表,上面有一些可信赖的认证中心 CA (Certificate Authority)和它们的公开密钥。 (2) 加密的 SSL 会话 客户和服务器交互的所有数据都在发送方加密,在接收
Navicat Premium是一个数据库开发工具,可让您从单个应用程序同时连接到MySQL,MariaDB,MongoDB,SQL Server,Oracle,PostgreSQL和SQLite数据库。与Amazon RDS,Amazon Aurora,Amazon Redshift,Microsoft Azure,Oracle Cloud,Google Cloud和MongoDB Atlas等云数据库兼容。您可以快速轻松地构建,管理和维护数据库。 设置数据源连接后,可以使用“导入向导”将数据从多种格式或从ODBC传输到数据库中。将数据从表/集合,视图或查询结果导出为Excel,Access,CSV等格式。使用我们的内置编辑器添加,修改和删除记录,您可以在Tree View,JSON View和类似电子表格的经典Grid View中方便地进行编辑。Navicat为您提供有效管理数据并确保流程平稳所需的工具。 Visual SQL / Query Builder将帮助您创建,编辑和运行SQL语句/查询,而不必担心语法和命令的正确用法。通过获取关键字建议并从编码中去除重复内容,使用“代码完成”和可自定义的代码段快速进行编码。使用我们的调试组件,例如设置断点,单步执行程序,查看和修改变量值以及检查调用堆栈,可以快速找到并纠正PL / SQL和PL / PGSQL编码错误。 使用我们专业的对象设计器创建,修改和管理所有数据库对象。使用复杂的数据库设计和建模工具将数据库转换为图形表示形式,以便您可以轻松地建模,创建和理解复杂的数据库。 我们的图表功能使您可以创建大型数据集的可视表示形式,并帮助您从数据中获得更深刻的见解。探索并发掘数据之间的模式,趋势和关系,并创建有效的视觉输出,以将您的发现显示在仪表板上以进行共享。 我们功能强大的本地备份/还原解决方案以及针对MongoDump,Oracle Data Pump和SQL Server Backup Utility的直观GUI,可指导您完成备份过程并减少潜在的错误。为可重复部署的过程设置自动化,例如在特定时间或日期执行数据库备份,MapReduce作业和脚本执行。无论您身在何处,都可以随时完成工作。 使用我们的内置模式可视化工具发现和探索您的MongoDB模式。分析文档并在集合中显示丰富的结构,以便您可以了解数据的架构,查找架构异常并轻松检查异常值。 通过SSH隧道和SSL建立安全连接,可确保每个连接都是安全,稳定和可靠的。支持不同的数据库服务器身份验证方法,例如MySQL和MariaDB的PAM身份验证,MongoDB的Kerberos和X.509身份验证以及PostgreSQL的GSSAPI身份验证。Navicat提供了更多的身份验证机制和高性能环境,因此您不必担心通过不安全的网络进行连接
一、首先你要确认你的鉴别模式: WIN NT鉴别模式呢还是混合模式,其中混合模式包括WIN NT鉴别模式和SQL SERVER 鉴别模式 实施鉴别模式的步骤 1、核实采用了可信连接 2、设置鉴别模式 3、关闭和重启MSSQLServer服务程序 4、创建WIN NT分组和用户 5、授权WIN NT分组和用户可存取SQL Server 6、为用非可信任连接的用户创建SQL Server登录帐号 二、为用户和角色分配登录帐号 三、给角色分配登录权 四、为用户和角色分配许可权限 在改进SQL Server 7.0系列所实现的安全机制的过程中,Microsoft建立了一种既灵活又强大的安全管理 机制,它能够对用户访问SQL Server服务器系统和数据库的安全进行全面地管理。按照本文介绍的步骤,你 可以为SQL Server 7.0(或2000)构造出一个灵活的、可管理的安全策略,而且它的安全性经得起考验。 一、验证方法选择 本文对验证(authentication)和授权(authorization)这两个概念作不同的解释。验证是指检验用户 的身份标识;授权是指允许用户做些什么。在本文的讨论中,验证过程在用户登录SQL Server的时候出现, 授权过程在用户试图访问数据或执行命令的时候出现。 构造安全策略的第一个步骤是确定SQL Server用哪种方式验证用户。SQL Server的验证是把一组帐户、密 码与Master数据库Sysxlogins表中的一个清单进行匹配。Windows NT/2000的验证是请求域控制器检查用户身 份的合法性。一般地,如果服务器可以访问域控制器,我们应该使用Windows NT/2000验证。域控制器可以是 Win2K服务器,也可以是NT服务器。无论在哪种情况下,SQL Server都接收到一个访问标记(Access Token)。 访问标记是在验证过程中构造出来的一个特殊列表,其中包含了用户的SID(安全标识号)以及一系列用户所 在组的SID。正如本文后面所介绍的,SQL Server以这些SID为基础授予访问权限。注意,操作系统如何构造访 问标记并不重要,SQL Server只使用访问标记中的SID。也就是说,不论你使用SQL Server 2000、SQL Server 7.0、Win2K还是NT进行验证都无关紧要,结果都一样。 如果使用SQL Server验证的登录,它最大的好处是很容易通过Enterprise Manager实现,最大的缺点在于 SQL Server验证的登录只对特定的服务器有效,也就是说,在一个多服务器的环境中管理比较困难。使用SQL Server进行验证的第二个重要的缺点是,对于每一个数据库,我们必须分别地为它管理权限。如果某个用户 对两个数据库有相同的权限要求,我们必须手工设置两个数据库的权限,或者编写脚本设置权限。如果用户数 量较少,比如25个以下,而且这些用户的权限变化不是很频繁,SQL Server验证的登录或许适用。但是,在几 乎所有的其他情况下(有一些例外情况,例如直接管理安全问题的应用),这种登录方式的管理负担将超过它 的优点。 二、Web环境中的验证 即使最好的安全策略也常常在一种情形前屈服,这种情形就是在Web应用中使用SQL Server的数据。在这 种情形下,进行验证的典型方法是把一组SQL Server登录名称和密码嵌入到Web服务器上运行的程序,比如 ASP页面或者CGI脚本;然后,由Web服务器负责验证用户,应用程序则使用它自己的登录帐户(或者是系统管 理员sa帐户,或者为了方便起见,使用Sysadmin服务器角色中的登录帐户)为用户访问数据。 这种安排有几个缺点,其中最重要的包括:它不具备对用户在服务器上的活动进行审核的能力,完全依 赖于Web应用程序实现用户验证,当SQL Server需要限定用户权限时不同的用户之间不易区别。如果你使用的 是IIS 5.0或者IIS 4.0,你可以用四种方法验证用户。第一种方法是为每一个网站和每一个虚拟目录创建一 个匿名用户的NT帐户。此后,所有应用程序登录SQL Server时都使用该安全环境。我们可以通过授予NT匿名 帐户合适的权限,改进审核和验证功能。 第二种方法是让所有网站使用Basic验证。此时,只有当用户在对话框中输入了合法的帐户和密码,IIS 才会允许他们访问页面。IIS依靠一个NT安全数据库实现登录身份验证,NT安全数据库既可以在本地服务器 上,也可以在域控制器上。当用户运行一个访问SQL Server数据库的程序或者脚本时,IIS把用户为了浏览 页面而提供的身份信息发送给服务器。如果你使用这种方法,应该记住:在通常情况下,浏览器与
爬虫SSLException是指在爬虫过程中出现的SSL异常错误。它通常是由于与目标网站建立SSL连接时出现问题导致的。根据提供的引用和,我们可以推断出问题可能是由于使用的爬虫框架webmagic在处理HTTPS链接时出现了错误。解决这个问题的一种方法是替换webmagic-core-0.7.3.jar这个jar包,如引用所示。当然,也可以尝试其他方法来解决SSLException,比如检查SSL证书是否正确,检查SSL协议版本是否被目标网站支持等。具体的解决方法还需要根据具体情况进行进一步的分析和调试。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [https Java SSLException protocol_version的问题解决方法](https://blog.csdn.net/weixin_30759083/article/details/114817622)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [webmagic-core-0.7.3.jar](https://download.csdn.net/download/qq_43964422/12921743)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值