1. <nobr id="easjo"><address id="easjo"></address></nobr>

      <track id="easjo"><source id="easjo"></source></track>
      1. 
        

      2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
      3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>
          貴州做網站公司
          貴州做網站公司~專業!靠譜!
          10年網站模板開發經驗,熟悉國內外開源網站程序,包括DEDECMS,WordPress,ZBlog,Discuz! 等網站程序,可為您提供網站建設,網站克隆,仿站,網頁設計,網站制作,網站推廣優化等服務。我們專注高端營銷型網站,企業官網,集團官網,自適應網站,手機網站,網絡營銷,網站優化,網站服務器環境搭建以及托管運維等。為客戶提供一站式網站解決方案?。?!

          klss(nginx怎么實現keyless)

          來源:互聯網轉載 時間:2024-05-08 06:44:44

          簡介

          當企業把業務遷移到云WAF/CDN邊緣節點上,需向云廠商提供業務的私鑰安全性不能得到保證,且若業務私鑰證書發生變化或頻繁修改需要受限于人。風險:一旦服務端的私鑰泄露會導致惡意攻擊者偽造虛假的服務器和客戶端通信,通信內容也存在被劫持和解密的風險。keyless源于clouldflare,采用keyless方案私鑰部署在客戶自己的服務器,無需向把業務私鑰部署在云/CDN邊緣節點上。

          clouldflare keyless項目地址:https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/

          cloudflare keyless開源項目地址:https://github.com/cloudflare/keyless

          相關基礎知識介紹:

          加解密套件知識普及

          MAC(Message authentication code):消息認證碼

          PRF(pseudorandom function):偽隨機函數

          SHA (Secure Hash Algorithm):安全散列算法

          • 對稱密碼:

          DES:是以64比特的明文為一個單位來進行加密的,密鑰長度是64比特

          三重DES: 就是將DES重復3次,有3個密鑰

          AES(Advanced Encryption Standard):是一種新標準的對稱密碼算法,已取代DES

          分組長度128比特,密鑰長度128、192、256三種規格

          • 分組密碼模式 :

          ECB(Electronic CodeBook):將明文分組加密之后的結果將直接成為密文分組

          CBC(Cipher Block Chaining):密文分組鏈接的模式

          CFB(Cipher FeedBack):密文反饋模式

          OFB(Output-Feedback):輸入反饋模式

          CTR(CounTeR):計數器模式

          GCM(Galois Counter Mode):Galois/計數器模式

          • 填充模式:對當明文長度不為分組長度的整數倍時,需要在最后一個分組中填充一些數據使其填滿一個分組長度,攻擊者會利用這個利用這個在最后一個分組填充一些數據。

          • 單向散列函數

          輸入的是消息輸出的是散列值,任意長度的消息計算出固定長度的散列值,消息不同散列值也不同

          應用:MD4、MD5;SHA-2系列(SHA-256,SHA-384,SHA-512,數字表示計算后的散列值長度)

          • 密鑰交換算法

          RSA本質上是為了解決密鑰配送的問題,密鑰配送的是配送的是運算對稱密鑰的關鍵信息,并不是對稱密鑰

          RSA:這是一個標準的密鑰交換算法,在ClientKeyExchange階段客戶端生成預主秘鑰,不支持向前保密,并以服務器公鑰加密傳送給服務器

          DHE_RSA:臨時Diffie-Hellman(ephemeral Diffie-Hellman, DHE),支持向前保密,缺點是執行緩慢,DHE是一種秘鑰協定算法,進行協商的團體都對密鑰生成產生作用,并對公共密鑰產生作用

          ECDHE_RSA和ECDHE_ECDSA:

          臨時橢圓曲線Diffe-Hellman(ephemeral elliptic curve Diffie-Hellman, ECDHE)密鑰交換建立在橢圓曲線加密的基礎之上。執行很快而且提供了向前保密,和DHE類似

          過濾了一臺設備上一天的數據

          加密套件

          完整名稱

          條數

          比例

          ECDHE-RSA-AES128-SHA256

          TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

          590549

          89.67%

          DHE-RSA-AES256-GCM-SHA384

          TLS_DHE_RSA_WITH_AES_256_GCM_SHA384

          33802

          5.13%

          ECDHE-RSA-AES256-GCM-SHA384

          TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

          18150

          2.76%

          DHE-RSA-AES256-SHA256

          TLS_DHE_RSA_WITH_AES_256_CBC_SHA256

          12845

          1.95%

          ECDHE-RSA-AES256-SHA

          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA

          1462

          0.22%

          ECDHE-RSA-CHACHA20-POLY1305

          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256

          1388

          0.21%

          AES256-SHA256

          TLS_RSA_WITH_AES_256_CBC_SHA256

          302

          0.05%

          ECDHE-RSA-AES128-GCM-SHA256

          TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

          36

          0.01%

          DHE-RSA-AES256-SHA

          TLS_DHE_RSA_WITH_AES_256_CBC_SHA

          23

          0%

          AES256-SHA

          TLS_RSA_WITH_AES_256_CBC_SHA

          1

          0%

          TLS握手中使用的密碼技術

          TLS記錄協議位于TLS協議的下層,是負責使用對稱密碼對消息進行加密通信(對消息壓縮、加密以及數據的認證)的部分

          • TLS握手協議中使用的密碼技術

          公鑰密碼:加密預主秘鑰用的

          單向散列函數:構成偽隨機數生成器

          數字簽名:驗證證書用的(單向散列函數計算公鑰密碼的散列值,加密后得到)

          偽隨機書生成器:生成預主秘鑰

          生成初始化向量(可以使用對稱密碼,單向散列函數來構建)?

          根據主密鑰生成密鑰(密碼參數)?

          • TLS記錄協議中使用的密碼技術

          對稱密碼(CBC模式):確保片段的機密性

          消息認證碼:確保片段的完整性并進行認證(單向散列函數和密鑰組合而成,也可以通過對稱密碼生成,應用單向散列函數計算密鑰+消息構成的)

          認證加密(AEAD,Authenticated-Encryption with Associated-Data用于關聯數據的認證加密):確保片段的完整性和機密性并進行認證?

          HTTPS中所用到的密碼技術

          證書:公鑰、數字簽名和指紋組合而成,一般講是基于指紋的數字簽名,一堆的東西就認證公鑰,為了保證不可否認行、認證、完整性

          Keyless原理

          總體架構

          密鑰交換算法類

          握手協議

          密鑰建立

          認證

          RSA

          RSA

          RSA

          DH

          DH

          RSA/DSA

          client random 是第1個隨機數R1(公開),對應wireshark抓包里“Client Hello”的Random

          server random 是第2個隨機數R2(公開),對應wireshark抓包里“Server Hello”的Random

          premaster 是第3個隨機數R3(私密),該隨機數是由客戶端創建,然后客戶端用服務端傳來的證書對premaster secret進行加密,生成premaster secret用來實際傳輸,對應抓包里的“Client Key Exchange”

          服務端用私鑰對premaster secret解密,得到premaster,這樣只有客戶端和服務端知道premaster

          最終,客戶端和服務端用公開的隨機數R1、R2、雙方私密的premaster(R3)組合起來,通過預定的算法生成一個hash值,作為之后的對話密鑰(session key)

          RSA密鑰交換算法主密鑰計算

          Client Random和Server Random明文傳輸,中間人可以直接查看,客戶端生成于中Premaster Secret后,如果有證書私鑰就可以直接通過這三個參數解得主密鑰

          標準RSAkeyless握手方案

          工作在:Server端的ChangeCipherSpec階段

          基于DH的完整握手主密鑰的計算

          從密鑰交換流程來說,DH算法和ECDHE一樣,二者的主要區別見該頁備注里的注意點1~3

          client random 是第1個隨機數R1(公開),對應wireshark抓包里“Client Hello”的Random ②a、server random 是第2個隨機數R2(公開),對應wireshark抓包里“Server Hello”的Random

          服務端自己創建一個隨機數或者 直接從證書中拿公鑰信息(圖例是拿公鑰信息),記為R3 ,結合上面的兩個公開的隨機數,通過DH算法算出來服務端DH參數=(R1 * R2 * R3) ,對應wireshark抓包里“Server Key Exchange”的Pubkey。

          服務端用私鑰,對兩個公開隨機數R1、R2和服務端的DH參數進行簽名,對應wireshark抓包里“Server Key Exchange”的Signature

          客戶端用證書公鑰驗證Signature,驗證服務端確實擁有私鑰后,客戶端就創建一個隨機數,記為R4,通過DH算法算出來客戶端DH參數=(R1 * R2 * R4) ,對應wireshark抓包里“Client Key Exchange”的Pubkey 。 這樣,客戶端和服務端用對方發來的DH參數,結合各自的私有隨機數R3或R4,分別計算得到相同的premaster = (R1 * R2 * R3 * R4) ,且只有客戶端和服務端知道premaster 最終,客戶端和服務端用公開的隨機數1、隨機數2、雙方私密的premaster組合起來,通過預定的算法生成一個hash值,作為之后的對話密鑰(session key)

          Server DH Parameter 是用證書私鑰簽名的,客戶端使用證書公鑰就可以驗證服務端合法性,相比 RSA 密鑰交換,DH 由傳遞 Premaster Scret 變成了傳遞 DH 算法所需的 Parameter,然后雙方各自算出 Premaster Secret。由于 Premaster Secret 無需交換,中間人就算有私鑰也無法獲得 Premaster Secret 和 Master Secret。

          ServerKeyExchange

          基于DH的keyless的完整握手

          工作在:Server端的ServerKeyExchange階段

          開源項目做了什么

          keyless server安裝和配置

          存儲給定的私鑰。

          使用加速卡(EXAR)進行解密,簽名操作。

          狀態信息統計。

          開源項目地址:https://github.com/cloudflare/keyless

          需要進行二次開發,開源版本很多細節處理的不好。

          On Centos:

          sudo yum install gcc automake libtool
          sudo yum install rpm-build rubybgems ruby-devel # only required for packages
          sudo gem install fpm --no-ri --no-rdoc # only required for packages

          安裝 make即可,make test測試

          參數說明 --port keyless server端的監聽端口

          --ip keyless server端監聽的ip

          --server-cert和--server-key簽發的證書

          --private-key-directory 用戶證書對應的私鑰存放文件夾

          --ca-file生成的根證書

          --pid-file pid文件

          --num-workers 線程數

          --verbose打印日志

          --daemon守護進程開啟

          nginx于keyless server交互?

          在SSL_do_handshake解密和簽名處理過程中增加一個keyless狀態。

          PREPARE REQUEST狀態,封裝keyless請求報文,然后將狀態設置為SEND REQUEST,SSL_do_handshake函數返回,nginx將keyless_connection的wev放到epoll里;

          SEND REQUEST狀態發送keyless請求,成功后將狀態設置為RECEIVE RESPONSE,SSL_do_handshake函數返回,nginx將keyless_connection的rev放到epoll里;

          RECEIVE RESPONSE狀態讀請求,全部讀完將狀態設置為FINISH;如果未讀完數據SSL_do_handshake函數返回,nginx將keyless_connection的rev放到epoll里;

          FINISH 繼續由openssl原有的邏輯處理。

          如果rev和wev超時,則關閉ssl_connection。

          nginx 處理https握手

          ngx_http_init_connection中recv→handler設置為ngx_http_ssl_handshake,把這個讀時間加入到epoll中,重點看handshake這個函數

          static void

          ngx_http_ssl_handshake(ngx_event_t *rev)

          {

          ...

          n = recv(c->fd, (char *) buf, size, MSG_PEEK);

          //判斷協議

          if (n == 1) {

          if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) {

          // 獲取loc conf和server conf

          clcf = ngx_http_get_module_loc_conf(hc->conf_ctx,

          ngx_http_core_module);


          if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {

          ngx_http_close_connection(c);

          return;

          }


          sscf = ngx_http_get_module_srv_conf(hc->conf_ctx,

          ngx_http_ssl_module);

          // 調用該函數生成ssl

          if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)

          != NGX_OK)

          {

          ngx_http_close_connection(c);

          return;

          }

          }

          }

          ...

          }

          ngx_int_t

          ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)

          {

          ...

          sc->session_ctx = ssl->ctx;


          sc->connection = SSL_new(ssl->ctx);


          if (sc->connection == NULL) {

          ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed");

          return NGX_ERROR;

          }


          if (SSL_set_fd(sc->connection, c->fd) == 0) {

          ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed");

          return NGX_ERROR;

          }

          ...

          }

          第一次收到client hello之后,完成初始化后調用ngx_ssl_handshake,其調用openssl的ssl_do_handshake

          ngx_int_t

          ngx_ssl_handshake(ngx_connection_t *c)

          {

          ...

          n = ngx_ssl_handshake_early_data(c);

          n = SSL_do_handshake(c->ssl->connection);

          ...

          }

          調用keyless模塊的init函數先是獲取coremodule的main conf,然后獲取到servers,遍歷這些servers的上下文中的srv conf配置,然后把sscf→ssl.ctx設置cert_cb為keyless_cert_handler,這個函數在api使用證書的時候會調用。

          static ngx_int_t

          ngx_http_ssl_keyless_init(ngx_conf_t *cf)

          {

          ...

          cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);


          cscfp = cmcf->servers.elts;


          for (s = 0; s < cmcf->servers.nelts; s++) {


          sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index];

          kscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_keyless_module.ctx_index];

          if (sscf->enable == 1 && kscf->enable == 1) {

          //TODO set prev cert callback handler.

          kscf->prev_ssl_cert_cb = ngx_http_lua_ssl_cert_handler;

          #endif

          SSL_CTX_set_cert_cb(sscf->ssl.ctx, ngx_http_ssl_keyless_cert_handler, NULL);


          }

          ...

          }

          cert handler做了了很多事情,初始化了很多nginx keyless相關的參數,核心在于這個函數新建了一條通向keyserver的連接。

          static int

          ngx_http_ssl_keyless_cert_handler(ngx_ssl_conn_t *ssl_conn, void *data)

          {

          ...

          if (ngx_http_ssl_keyless_get_keyserver_pc(klss) != NGX_OK) {

          ngx_log_error(NGX_LOG_ERR, c->log, 0, "init keyless sess");

          }


          klss_state->data = klss;

          klss_state->state = KEYLESS_STATE_RSA_INIT;


          c->klss = klss;

          pc = klss->pc;


          rc = ngx_event_connect_peer(klss->pc);

          pcc = ((ngx_peer_connection_t *)klss->pc)->connection;


          pcc->data = klss;

          pcc->write->handler = ngx_http_ssl_keyless_keyserver_handler;

          pcc->read->handler = ngx_http_ssl_keyless_keyserver_handler;

          ...

          }

          static ngx_int_t

          ngx_http_ssl_keyless_get_keyserver_pc(ngx_http_keyless_sess_t *klss)

          {

          ...

          pc->get = ngx_http_ssl_keyless_peer_get;

          pc->free = ngx_http_ssl_keyless_peer_free;

          ...

          }

          do handshake的時候調用的是openssl的async job的庫,相當于新開一個函數棧

          ASYNC JOB

          int SSL_do_handshake(SSL *s)

          {

          ...

          if (SSL_in_init(s) || SSL_in_before(s)) {

          if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {

          struct ssl_async_args args;


          args.s = s;


          ret = ssl_start_async_job(s, &args, ssl_do_handshake_intern);

          } else {

          ret = s->handshake_func(s);

          }

          }

          ...

          }

          int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret,

          int (*func)(void *), void *args, size_t size)

          {

          ...

          /* Start a new job */

          if ((ctx->currjob = async_get_pool_job()) == NULL)

          return ASYNC_NO_JOBS;

          ...

          }

          static ASYNC_JOB *async_get_pool_job(void) {

          ...

          if (job == NULL) {

          /* Pool is empty */

          if ((pool->max_size != 0) && (pool->curr_size >= pool->max_size))

          return NULL;


          job = async_job_new();

          if (job != NULL) {

          if (! async_fibre_makecontext(&job->fibrectx)) {

          async_job_free(job);

          return NULL;

          }

          pool->curr_size++;

          }

          }

          ...

          }

          先做初始化get下context,malloc一個stack,這個堆棧創建完成后把函數放進去,使用makecontext來創建一旦調用就會運行該函數,async_start_func本身使用當前job中的func,函數也是傳進來的參數

          int async_fibre_makecontext(async_fibre *fibre)

          {

          fibre->env_init = 0;

          if (getcontext(&fibre->fibre) == 0) { //初始化當前ucontext

          fibre->fibre.uc_stack.ss_sp = OPENSSL_malloc(STACKSIZE);

          if (fibre->fibre.uc_stack.ss_sp != NULL) {

          fibre->fibre.uc_stack.ss_size = STACKSIZE;

          fibre->fibre.uc_link = NULL;

          makecontext(&fibre->fibre, async_start_func, 0);

          return 1;

          }

          } else {

          fibre->fibre.uc_stack.ss_sp = NULL;

          }

          return 0;

          }

          Pausejob最關鍵的是swapcontext,這個在func中一旦被調用的話,就可以立即切換棧信息,切回start_job的主函數,根據job→status=ASYNC_JOB_PAUSING來返回

          int ASYNC_pause_job(void)

          {

          ...

          if (!async_fibre_swapcontext(&job->fibrectx,

          &ctx->dispatcher, 1)) {

          ASYNCerr(ASYNC_F_ASYNC_PAUSE_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT);

          return 0;

          }

          ...

          }

          切回主函數之后,因為startjob是for死循環,所以會根據job的狀態進行返回

          int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret,

          int (*func)(void *), void *args, size_t size)

          {

          ...

          for (;;) {

          if (ctx->currjob != NULL) {

          if (ctx->currjob->status == ASYNC_JOB_PAUSING) {

          *job = ctx->currjob;

          ctx->currjob->status = ASYNC_JOB_PAUSED;

          ctx->currjob = NULL;

          return ASYNC_PAUSE;

          }

          if (ctx->currjob->status == ASYNC_JOB_PAUSED) {

          ctx->currjob = *job;

          /* Resume previous job */

          if (!async_fibre_swapcontext(&ctx->dispatcher,

          &ctx->currjob->fibrectx, 1)) {

          ASYNCerr(ASYNC_F_ASYNC_START_JOB,

          ASYNC_R_FAILED_TO_SWAP_CONTEXT);

          goto err;

          }

          continue;

          }

          ...

          }

          static int ssl_start_async_job(SSL *s, struct ssl_async_args *args,

          int (*func) (void *))

          {

          ...

          switch (ASYNC_start_job(&s->job, s->waitctx, &ret, func, args,

          sizeof(struct ssl_async_args))) {

          case ASYNC_ERR:

          s->rwstate = SSL_NOTHING;

          SSLerr(SSL_F_SSL_START_ASYNC_JOB, SSL_R_FAILED_TO_INIT_ASYNC);

          return -1;

          case ASYNC_PAUSE:

          s->rwstate = SSL_ASYNC_PAUSED;

          return -1;

          }

          ...

          }

          返回的這個狀態碼,在nginx里面接到就是SSL_ERROR_WANT_ASYNC

          關鍵就是調用async_pause_job交還給nginx來做keyless處理,以及將與keyserver的狀態調整為presend。

          int kls_rsa_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)

          {

          ...

          waitctx = ASYNC_get_wait_ctx(job);

          ASYNC_WAIT_CTX_get_fd(waitctx, (void *)waitctx, &fd, (void *)&klss_state);

          if (klss_state->state == KEYLESS_STATE_RSA_INIT) {

          klss_state->is_rsa_decrypt = 1;

          dec_ctx = &klss_state->dec_ctx;

          dec_ctx->from = from;

          dec_ctx->to = to;

          dec_ctx->flen = flen;

          dec_ctx->padding = padding;

          klss_state->state = KEYLESS_STATE_RSA_PRE_SEND;

          ASYNC_pause_job();

          }

          ...

          }

          這里處理完交還給nginx,之后nginx 就可以做原本由openssl實現的加解密。

          重寫engine重寫兩個關鍵函數

          static int bind_helper(ENGINE *e)

          {

          kls_rsa_meth = RSA_meth_new("keyless rsa method", RSA_METHOD_FLAG_NO_CHECK);

          RSA_meth_set_sign(kls_rsa_meth, kls_rsa_sign);

          RSA_meth_set_priv_dec(kls_rsa_meth, kls_rsa_private_decrypt);



          if (!ENGINE_set_id(e, engine_keyless_id) ||

          !ENGINE_set_name(e, engine_keyless_name) ||

          !ENGINE_set_RSA(e, kls_rsa_meth)) {


          return 0;

          }


          return 1;

          }


          static ENGINE *ENGINE_keyless(void)

          {

          ENGINE *e = ENGINE_new();

          if (e == NULL)

          return NULL;

          if (!bind_helper(e)) {

          ENGINE_free(e);

          return NULL;

          }

          return e;

          }


          void engine_load_keyless_int(void)

          {

          ENGINE *e = ENGINE_keyless();

          if (e == NULL) {

          return;

          }


          ENGINE_add(e);

          ENGINE_free(e);

          ERR_clear_error();


          return;

          }

          重寫的兩個函數是sign和priv_dec

          struct rsa_meth_st {

          int (*rsa_priv_dec) (int flen, const unsigned char *from,

          unsigned char *to, RSA *rsa, int padding);

          int (*rsa_sign) (int type,

          const unsigned char *m, unsigned int m_length,

          unsigned char *sigret, unsigned int *siglen,

          const RSA *rsa);

          }


          int kls_rsa_sign(int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, const RSA *rsa)

          {

          ...

          waitctx = ASYNC_get_wait_ctx(job);

          ASYNC_WAIT_CTX_get_fd(waitctx, (void *)waitctx, &fd, (void *)&klss_state);


          if (klss_state->state == KEYLESS_STATE_RSA_INIT) {

          klss_state->is_rsa_sign = 1;

          sign_ctx = &klss_state->sign_ctx;

          sign_ctx = &klss_state->sign_ctx;

          sign_ctx->type = type;

          sign_ctx->m = m;

          sign_ctx->m_length = m_length;

          klss_state->state = KEYLESS_STATE_RSA_PRE_SEND;

          ASYNC_pause_job();

          }

          ...

          }

          調用pause時最重要邏輯是async_fibre_swapcontext,這個函數是用于切換的核心,同時進行初始化操作,把函數放到新開辟棧里運行。

          static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r)

          {

          o->env_init = 1;


          if (!r || !_setjmp(o->env)) {

          if (n->env_init)

          _longjmp(n->env, 1);

          else

          setcontext(&n->fibre);

          }


          return 1;

          }

          “nginx怎么實現keyless”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注本站網站,小編將為大家輸出更多高質量的實用文章!

          標簽:klss-

          c語言中正確的字符常量是用一對單引號將一個字符括起表示合法的字符常量。例如‘a’。數值包括整型、浮點型。整型可用十進制,八進制,十六進制。八進制前面要加0,后面...

          2022年天津專場考試原定于3月19日舉行,受疫情影響確定延期,但目前延期后的考試時間推遲。 符合報名條件的考生,須在規定時間登錄招考資訊網(www.zha...

          :喜歡聽,樂意看。指很受歡迎?!巴卣官Y料”喜聞樂見:[ xǐ wén lè jiàn ]詳細解釋1. 【解釋】:喜歡聽,樂意看。指很受歡迎。2. 【示例】:這是...

          2022年全球十大商品貿易公司1、維多集團維多集團(Vitol Group)是全球更大的石油和天然氣實物貿易商,原油是其能源業務中最重要的部分。其他商品貿易包括:糖,金屬和谷物。維多集團每年運送超過3.5億噸原油,并將250艘超級油輪和其他船運往世界各地。 它平均每天處理超過700萬桶石油和產品-大約2、嘉能可國際嘉能可國際(Glencore ***ernational)是金屬,礦物和石油的更大貿...

          中國石油三巨頭是哪幾個?中國的石油三頭是中國石油天然氣集團有限公司、中國海洋石油總公司、中國石油化工集團有限公司。而如果是世界范圍內的石油三巨頭,很難有所高低,比較具有代表性的有沙特阿美、??松梨谶€有俄羅斯石油公司。中國石天然氣集團有限公司也可以簡稱為中石油、中國石油, 國有重要骨干企業。以汽油業務、石油工程建設、工程技術服務、新能源開發等為主營業務的國際能源公司。中國海洋石集團有限公司是中國國...

          能在自己家里找到安寧的人是最幸福的人。作者:每晚五月一個家庭想好最重要的是什么?其實答案早就被我小時候畫的畫告訴了。小時候我們用橫梁、屋頂、墻壁、柵欄、樹木粉刷一棟房子做裝飾,一棟房子就完工了。很簡單,但就是這些簡單的東西,才構成了一個完整的家。其實生活就像繪畫一樣,有它的梁,有它的屋頂,有它的墻,有它的裝飾,這是房子的風水,也是生活的風水。養好這四種風水,一家興旺。01是支撐全家的健康梁。一個家...

          TOP
          国产初高中生视频在线观看|亚洲一区中文|久久亚洲欧美国产精品|黄色网站入口免费进人
          1. <nobr id="easjo"><address id="easjo"></address></nobr>

              <track id="easjo"><source id="easjo"></source></track>
              1. 
                

              2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
              3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>