陳宥僑
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Versions and GitHub Sync Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
Invitee
Publish Note

Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

Your note will be visible on your profile and discoverable by anyone.
Your note is now live.
This note is visible on your profile and discoverable online.
Everyone on the web can find and read all notes of this public team.
See published notes
Unpublish note
Please check the box to agree to the Community Guidelines.
View profile
Engagement control
Commenting
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
  • Everyone
Suggest edit
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
Emoji Reply
Enable
Import from Dropbox Google Drive Gist Clipboard
   owned this note    owned this note      
Published Linked with GitHub
Subscribed
  • Any changes
    Be notified of any changes
  • Mention me
    Be notified of mention me
  • Unsubscribe
Subscribe
--- title: "[行動網路安全] Project2 程式說明" tags: Mobile Network Security --- [行動網路安全] Project2 程式說明 === - Project2 說明: <https://hackmd.io/QLSj036NSAmIHJXDA3SfQA?both> ## Todo Check List ### ./src/dev.c - 填寫 struct `sockaddr_ll addr`,用於在函式 `set_sock_fd` 中 bind - 把整個訊框儲存到 `self->frame` ```c= #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <unistd.h> #include <string.h> #include <time.h> #include <sys/ioctl.h> #include <net/if.h> #include <linux/if_ether.h> #include <arpa/inet.h> #include "dev.h" #include "net.h" #include "esp.h" #include "replay.h" #include "transport.h" // 結構 ifreq 定義在 /usr/include/net/if.h,用來配置和獲取ip位址、遮罩及 MTU 等接口訊息。 inline static int get_ifr_mtu(struct ifreq *ifr) { int fd; // 建立 socket // PF_PACKET 17,Packet family 底層資料包介面 // SOCK_RAW 3,ip Raw protocol interface,可以接收到本機網路卡上的資料訊框或者資料包,用於監聽網路的流量和分析 // IPPROTO_IP,Dummy protocol for TCP if ((fd = socket(PF_PACKET, SOCK_RAW, 0)) < 0) { perror("socket()"); exit(EXIT_FAILURE); // 回傳 1,表示沒有成功執行 } // ioctl 是設備驅動程序中對設備的 I/O 通道進行管理的函數 if (ioctl(fd, SIOCGIFMTU, ifr) < 0) { perror("ioctl()"); close(fd); exit(EXIT_FAILURE); } // 回傳 ifr 的 mtu (最大傳輸單元) return ifr->ifr_mtu; } inline static struct sockaddr_ll init_addr(char *name) { struct sockaddr_ll addr; // 把記憶體字符串的前 n 個 bytes 變為 0 // void bzero(void *s, int n); bzero(&addr, sizeof(addr)); // 如果要從指定乙太網路介面上的獲取封包時, // 在 struct sockaddr_ll 中指定網路介面,绑定 (bind) 封包到該介面上。 // 只有 sll_protocol 和 sll_ifindex 這兩個位址字段是用來 bind 的。 // [TODO]: Fill up struct sockaddr_ll addr which will be used to bind in func set_sock_fd addr.sll_ifindex = *name; addr.sll_family = PF_PACKET; addr.sll_protocol = htons(ETH_P_ALL); if (addr.sll_ifindex == 0) { perror("if_nameindex()"); exit(EXIT_FAILURE); } return addr; } inline static int set_sock_fd(struct sockaddr_ll dev) { // dev: self->addr int fd; // 接收完整的資料鏈結層訊框 if ((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { perror("socket()"); exit(EXIT_FAILURE); } bind(fd, (struct sockaddr *)&dev, sizeof(dev)); return fd; } void fmt_frame(Dev *self, Net net, Esp esp, Txp txp) { // 把訊框存入 self->frame,以及其長度存入 self->framelen // [TODO]: store the whole frame into self->frame // and store the length of the frame into self->framelen // self->framelen = LINKHDRLEN + net.hdrlen + sizeof(EspHeader) + txp.hdrlen + txp.plen + sizeof(EspTrailer) + esp.authlen; self->frame = self->linkhdr; self->framelen = LINKHDRLEN + net.hdrlen + net.plen; } ssize_t tx_frame(Dev *self) { if (!self) { fprintf(stderr, "Invalid arguments of %s.", __func__); return -1; } // ssize_t 是 signed size_t ssize_t nb; // socklen_t 和 int 相同 socklen_t addrlen = sizeof(self->addr); // sendto() 將資料由指定的 socket 傳給對方主機,參數 s 為已建好連線的 socket。 nb = sendto(self->fd, self->frame, self->framelen, 0, (struct sockaddr *)&self->addr, addrlen); if (nb <= 0) perror("sendto()"); return nb; } ssize_t rx_frame(Dev *self) { if (!self) { fprintf(stderr, "Invalid arguments of %s.", __func__); return -1; } ssize_t nb; socklen_t addrlen = sizeof(self->addr); nb = recvfrom(self->fd, self->frame, self->mtu, 0, (struct sockaddr *)&self->addr, &addrlen); if (nb <= 0) perror("recvfrom()"); return nb; } void init_dev(Dev *self, char *dev_name) { if (!self || !dev_name || strlen(dev_name) + 1 > IFNAMSIZ) { fprintf(stderr, "Invalid arguments of %s.", __func__); exit(EXIT_FAILURE); } struct ifreq ifr; // sprintf 用來格式化字串 // snprintf 限制最大的字串長度 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", dev_name); self->mtu = get_ifr_mtu(&ifr); self->addr = init_addr(dev_name); self->fd = set_sock_fd(self->addr); self->frame = (uint8_t *)malloc(BUFSIZE * sizeof(uint8_t)); self->framelen = 0; self->fmt_frame = fmt_frame; self->tx_frame = tx_frame; self->rx_frame = rx_frame; self->linkhdr = (uint8_t *)malloc(LINKHDRLEN); } ``` #### 說明 - [第19行] ifreq: 用於 socket ioctl 的介面請求結構。所有介面 ioctl 必須具有以 ifr_name 開頭的參數定義。其餘可能是特定於介面的。 ```c struct ifreq { # define IFHWADDRLEN 6 # define IFNAMSIZ IF_NAMESIZE union{ char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */ } ifr_ifrn; union{ struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short int ifru_flags; int ifru_ivalue; int ifru_mtu; struct ifmap ifru_map; char ifru_slave[IFNAMSIZ]; /* Just fits the size */ char ifru_newname[IFNAMSIZ]; __caddr_t ifru_data; } ifr_ifru; }; ``` - [第30行] ioctl: 系統調用操作特殊檔案的底層裝置參數。特別是,字元特殊檔案(例如終端機)的許多操作特性可以透過 ioctl() 請求進行控制。參數 fd 必須是 open file descriptor。第二個參數是裝置相關的請求程式碼。第三個參數是指向記憶體的無型別指針。傳統上它是 `char *argp`(從 void * 是有效 C 之前的日子開始)。 ```c= #include <sys/ioctl.h> int ioctl(int fd, unsigned long request, ...); ``` - [第50行] ```c= struct sockaddr_ll { unsigned short sll_family; /* Always AF_PACKET */ unsigned short sll_protocol; /* Physical-layer protocol */ int sll_ifindex; /* Interface number */ unsigned short sll_hatype; /* ARP hardware type */ unsigned char sll_pkttype; /* Packet type */ unsigned char sll_halen; /* Length of address */ unsigned char sll_addr[8]; /* Physical-layer address */ }; ``` sll_protocol: 標準乙太網路協定類型,按照網路位元組順序。 sll_ifindex: interface 索引,0 代表所有的網路介面。 - [第75行] ```c= struct dev { int mtu; struct sockaddr_ll addr; int fd; unit8_t *frame; unit16_t *framelen; unit8_t *linkhdr; void (*fmt_frame)(Dev *self, Net net, Esp esp, Txp txp); ssize_t (*tx_frame)(Dev *self); ssize_t (*rx_frame)(Dev *self); }; struct esp{ EspHeader hdr; unit8_t *pl; // ESP payload size_t plen; // ESP payload length unit8_t *pad; // ESP padding EspTrailer tlr; unit8_t *auth; size_t authlen; unit8_t *esp_key; unit8_t *(*set_padpl)(Esp *self); unit8_t *(*set_auth)(Esp *self, ssize_t (*hmac)(unit8_t const * size_t, unit8_t const *, size_t unit8_t *)); void (*get_key)(Esp *self); unit8_t *(*dissect)(Esp *self, unit8_t *esp_pkt, size_t esp_len); Esp *(*fmt_rep)(Esp *self, Proto p); }; typedef enum proto { UNKN_PROTO = 0, IPv4 = IPPROTO_IP, // 0, Dummy protocol for TCP. ESP = IPPROTO_ESP, // 50, ESP. TCP = IPPROTO_TCP, // 6, Transmission Control Protocol. } Proto; struct net{ char *src_ip; char *dst_ip; char *x_src_ip; /* Expected src IP addr */ char *x_dsc_ip; /* Expected dst IP addr */ struct iphdr ip4hdr; size_t hdrlen; unit16_t plen; Proto pro; unit8_t *(*dissect)(Net *self, unit8_t *pkt, size_t pkt_len); Net *(*fmt_req)(Net *self); }; ``` ### ./src/transport.c - 完成 TCP checksum 計算 - 收集 `segm` 資訊 - 填寫 `self->tcphdr` ```c= #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <unistd.h> #include <netinet/ip.h> #include <netinet/in.h> #include <arpa/inet.h> #include "net.h" #include "transport.h" uint16_t cal_tcp_cksm(struct iphdr iphdr, struct tcphdr tcphdr, uint8_t *pl, int plen) { // [TODO]: Finish TCP checksum calculation // 計算 TCP checksum // 參考: https://gist.github.com/david-hoze/0c7021434796997a4ca42d7731a7073a uint16_t cksm = 0; size_t tcpLen; tcpLen = sizeof(tcphdr) + plen; //add the pseudo header //the source ip cksm += (iphdr.saddr >> 16) & 0xFFFF; cksm += (iphdr.saddr) & 0xFFFF; //the dest ip cksm += (iphdr.daddr >> 16) & 0xFFFF; cksm += (iphdr.daddr) & 0xFFFF; //protocol and reserved: 6 cksm += htons(IPPROTO_TCP); //the length cksm += htons(tcpLen); //add the IP payload while (tcpLen > 1) { cksm += * pl++; tcpLen -= 2; } //if any bytes left, pad the bytes and add if(tcpLen > 0) { //printf("+++++++++++padding, %dn", tcpLen); cksm += ((*pl)&htons(0xFF00)); } //Fold 32-bit sum to 16 bits: add carrier to result while (cksm >> 16) { cksm = (cksm & 0xffff) + (cksm >> 16); } cksm = ~cksm; //return computation result return cksm } uint8_t *dissect_tcp(Net *net, Txp *self, uint8_t *segm, size_t segm_len) { // [TODO]: Collect information from segm // (Check IP addr & port to determine the next seq and ack value) // Return payload of TCP self->pl = segm + self->hdrlen; // reference from replay.c struct tcphdr *thdr = (struct tcphdr *)(segm); self->thdr.th_sport = *segm; self->thdr.th_dport = *(segm+2); self->thdr.th_seq = *(segm+4); self->thdr.th_ack = *(segm+8); self->thdr.th_win = *(segm+14); self->thdr.th_sum = *(segm+16); self->thdr.th_urp = *(segm+18); if(strcmp(net->x_src_ip, net->src_ip) == 0) { self->x_tx_seq = ntohl(self->thdr.th_seq) + self->plen; self->x_tx_ack = ntohl(self->thdr.th_ack); self->x_src_port = ntohs(self->thdr.th_sport); self->x_dst_port = ntohs(self->thdr.th_dport); } if (strcmp(net->x_src_ip, net->dst_ip) == 0) { self->x_tx_seq = ntohl(self->thdr.th_ack); self->x_tx_ack = ntohl(self->thdr.th_seq) + txp->plen; self->x_src_port = ntohs(self->thdr.th_dport); self->x_dst_port = ntohs(self->thdr.th_sport); } return self->pl; } Txp *fmt_tcp_rep(Txp *self, struct iphdr iphdr, uint8_t *data, size_t dlen) { // [TODO]: Fill up self->tcphdr (prepare to send) // https://stackoverflow.com/questions/36292016/c-create-tcp-syn-without-filling-ip-header-using-raw-socket //struct tcphdr *tcp = (struct tcphdr *) dlen + sizeof(iphdr); //tcp->source = htons(atoi("6668")); // source port //tcp->dest = htons(atoi("3868")); // destination port self->thdr.source = htons(self->x_src_port); self->thdr.dest = htons(self->x_dst_port); self->thdr.seq = htons(self->x_tx_seq); // inital sequence number self->thdr.ack_seq = htons(self->x_tx_ack); // acknowledgement number self->thdr.ack = 1; // acknowledgement flag self->thdr.syn = 1; // synchronize flag self->thdr.rst = 0; // reset flag self->thdr.psh = 1; // push flag self->thdr.fin = 0; // finish flag self->thdr.urg = 0; // urgent flag self->thdr.check = 0; // tcp checksum self->thdr.doff = 0; // data offset //self->tcphdr = tcp; return self; } inline void init_txp(Txp *self) { self->pl = (uint8_t *)malloc(IP_MAXPACKET * sizeof(uint8_t)); self->hdrlen = sizeof(struct tcphdr); self->dissect = dissect_tcp; self->fmt_rep = fmt_tcp_rep; } ``` #### 說明 - Txp ```c= struct txp { uint16_t x } ``` ### ./src/net.c - 完成 IP checksum 計算 - 收集 `pkt` 資訊 - 從 SAD dump 身份驗證密鑰 ```c= #include <arpa/inet.h> #include <netdb.h> #include <netinet/in.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ifaddrs.h> #include <unistd.h> #include "net.h" #include "transport.h" #include "esp.h" uint16_t cal_ipv4_cksm(struct iphdr iphdr) { // [TODO]: Finish IP checksum calculation // 參考: https://blog.csdn.net/one_clouder/article/details/52987837 iphdr.check = ip_fast_csum(iphdr, iphdr.ihl); return iphdr.check; } uint8_t *dissect_ip(Net *self, uint8_t *pkt, size_t pkt_len) { // [TODO]: Collect information from pkt. // Return payload of network layer pkt = pkt + self->hdrlen; self->plen = pkt_len - self->hdrlen; return pkt; } Net *fmt_net_rep(Net *self) { // [TODO]: Fill up self->ip4hdr (prepare to send) self->ip4hdr.check = cal_ipv4_cksm(self->ip4hdr); self->ip4hdr.tot_len = self->plen + self->hdrlen; return self; } void init_net(Net *self) { if (!self) { fprintf(stderr, "Invalid arguments of %s.", __func__); exit(EXIT_FAILURE); } self->src_ip = (char *)malloc(INET_ADDRSTRLEN * sizeof(char)); self->dst_ip = (char *)malloc(INET_ADDRSTRLEN * sizeof(char)); self->x_src_ip = (char *)malloc(INET_ADDRSTRLEN * sizeof(char)); self->x_dst_ip = (char *)malloc(INET_ADDRSTRLEN * sizeof(char)); self->hdrlen = sizeof(struct iphdr); self->dissect = dissect_ip; self->fmt_rep = fmt_net_rep; } ``` #### 說明 - iphdr ```c= struct iphdr { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int ihl:4; unsigned int version:4; #elif __BYTE_ORDER == __BIG_ENDIAN unsigned int version:4; unsigned int ihl:4; #else #error "Please fix <bits/endian.h>" #endif uint16_t tot_len; uint16_t id; uint16_t frag_off; uint8_t ttl; uint8_t protocol; uint16_t check; uint32_t saddr; uint32_t daddr; }; ``` ### ./src/esp.c - 填寫 `self->pad` 和 `self->pad_len`(參考 RFC4303 Session 2.4) - 把所有需要驗證的東西都放到 `buff` 並加上 `nb` - 收集 `esp_pkt` 資訊 - 填寫 ESP `header` 和 `tailer` ```c= #include <stdio.h> #include <string.h> #include <unistd.h> #include <linux/pfkeyv2.h> #include "esp.h" #include "transport.h" #include "hmac.h" EspHeader esp_hdr_rec; void get_ik(int type, uint8_t *key) { // [TODO]: Dump authentication key from security association database (SADB) // (Ref. RFC2367 Section 2.3.4 & 2.4 & 3.1.10) // https://www.masterraghu.com/subjects/np/introduction/unix_network_programming_v1.3/ch19lev1sec3.html /* * struct sadb_key { * uint16_t sadb_key_len; * uint16_t sadb_key_exttype; * uint16_t sadb_key_bits; * uint16_t sadb_key_reserved; * }; */ /* sizeof(struct sadb_key) == 8 */ /* struct sadb_key sadb_k; sadb_k.sadb_key_len = 8; sadb_k.sadb_key_exttype = SADB_EXT_KEY_AUTH; sadb_k.sadb_key_bits = 1; sadb_k.sadb_key_reserved = 32; */ key->sadb_key_len = 8; key->sadb_key_exttype = type; /* sadb_key_bits: The length of the valid key data, in bits. * A value of zero in sadb_key_bits MUST cause an error. */ key->sadb_key_bits = 1; key->sadb_key_reserved = 32; } void get_esp_key(Esp *self) { get_ik(SADB_SATYPE_ESP, self->esp_key); } uint8_t *set_esp_pad(Esp *self) { // [TODO]: Fiill up self->pad and self->pad_len (Ref. RFC4303 Section 2.4) uint8_t padding[256 - sizeof(self)] = {0}; self->pad = padding; self->tlr.pad_len = 256 - sizeof(self); return self->pad; } uint8_t *set_esp_auth(Esp *self, ssize_t (*hmac)(uint8_t const *, size_t, uint8_t const *, size_t, uint8_t *)) { if (!self || !hmac) { fprintf(stderr, "Invalid arguments of %s().\n", __func__); return NULL; } uint8_t buff[BUFSIZE]; size_t esp_keylen = 16; size_t nb = 0; // Number of bytes to be hashed ssize_t ret; // [TODO]: Put everything needed to be authenticated into buff and add up nb ret = hmac(self->esp_key, esp_keylen, buff, nb, self->auth); if (ret == -1) { fprintf(stderr, "Error occurs when try to compute authentication data"); return NULL; } self->authlen = ret; return self->auth; } uint8_t *dissect_esp(Esp *self, uint8_t *esp_pkt, size_t esp_len) { // [TODO]: Collect information from esp_pkt. // Return payload of ESP self->pl = esp_pkt + sizeof(EspHeader); // 加上 ESP header 長度後即為 ESP payload self->plen = esp_len - sizeof(EspHeader); return self->pl; } Esp *fmt_esp_rep(Esp *self, Proto p) { // [TODO]: Fill up ESP header and trailer (prepare to send) // Proto p = TCP = 6; self->hdr.seq = ntohl(self->hdr.seq) + 1;// Sequence number self->tlr.pad_len = 3;// Pad Length(8 bits) self->tlr.nxt = p; // Next Header(8 bits) return self; } void init_esp(Esp *self) { self->pl = (uint8_t *)malloc(MAXESPPLEN * sizeof(uint8_t)); self->pad = (uint8_t *)malloc(MAXESPPADLEN * sizeof(uint8_t)); self->auth = (uint8_t *)malloc(HMAC96AUTHLEN * sizeof(uint8_t)); self->authlen = HMAC96AUTHLEN; self->esp_key = (uint8_t *)malloc(BUFSIZE * sizeof(uint8_t)); self->set_padpl = set_esp_pad; self->set_auth = set_esp_auth; self->get_key = get_esp_key; self->dissect = dissect_esp; self->fmt_rep = fmt_esp_rep; } ``` #### 說明 - RFC2367 Section 2.3.4 Key Extension ```c= struct sadb_key { uint16_t sadb_key_len; uint16_t sadb_key_exttype; uint16_t sadb_key_bits; uint16_t sadb_key_reserved; }; /* sizeof(struct sadb_key) == 8 */ ``` key extension 有兩種。AUTH 版本與身份驗證密鑰(例如 IPsec AH、OSPF MD5)一起使用,而 ENCRYPT 版本與加密密鑰(例如 IPsec ESP)一起使用。 PF_KEY 只處理完全形成的加密密鑰,而不是「原始密鑰材料」。例如,當使用 ISAKMP/Oakley 時,key management daemon 始終負責將 Diffie-Hellman 計算的結果轉換為不同的完整密鑰,然後再通過 PF_KEY 將這些密鑰發送到 kernel。制定此規則是因為 PF_KEY 主要在支持多種安全協定(不僅僅是 IP security)以及多種密鑰管理方案,包括手動密鑰,它沒有「原始密鑰材料」的概念。一個乾淨的、獨立於協定的介面對於不同操作系統的可移植性以及對不同安全協議的可移植性很重要。 如果演算法定義其密鑰包含 parity bits(例如 DES),那麼與 PF_KEY 一起使用的密鑰也必須包含這些 parity bits。例如,這意味著單個 DES 密鑰始終是 64-bit 數量。 當特定的安全協定只需要一個驗證和/或一個加密密鑰時,使用適當的密鑰擴展傳輸完整的密鑰。當一個特定的安全協定需要多個密鑰來實現相同的功能時(例如,使用 2 或 3 個密鑰的三重 DES 和非對稱演算法),那麼這兩個完全形成的密鑰必須按照用於 outbound 封包處理的順序連接在一起。在多個密鑰的情況下,演算法必須能夠根據提供的資訊確定各個密鑰的長度。總密鑰長度(結合所使用演算法的知識)通常提供足夠的資訊來進行此確定。 密鑰總是按照它們用於 outbound 封包處理的順序通過 PF_KEY 介面。對於 inbound 處理,使用 key 的正確順序可能與用於 PF_KEY 介面的規範串聯順序不同。 在 inbound 和 outbound 處理中以正確的順序使用密鑰是實現的責任。 例如,考慮一對使用 ESP 三密鑰 Triple-DES SA 進行單播通訊的節點。傳送者節點上的 outbound SA 和 接收者節點上的 inbound SA 都將在各自的 ENCRYPT 密鑰擴展中包含密鑰 A,然後是密鑰 B,然後是密鑰 C。 outbound SA 將首先使用密鑰 A,然後是密鑰 B,然後在加密時使用密鑰 C。 inbound SA 將使用密鑰 C,然後是密鑰 B,然後在解密時使用密鑰 A。(Note: 我們知道 3DES 實際上是加密-解密-加密。)密鑰 A、密鑰 B、密鑰 C 的規範順序用於 3DES,並且應該記錄在案。「加密」的順序是這個例子的規範順序。[Sch96] Key data bits從 most-significant 到 least significant 排列。例如,一個 22-bit 密鑰將佔用三個八位位元組,其中最低有效兩位不包含密鑰材料。然後將使用五個額外的八位位元組填充到下一個 64-bit boundary。 雖然與 PF_KEY 沒有直接關係,但存在與密鑰的奇數十六進位表示有關的使用者界面問題。考慮 16-bit 數字的例子: 0x123 這將需要兩個八位位元組的存儲空間。但是,在沒有其他資訊的情況下,不清楚顯示的值是否存儲為: 01 23 OR 12 30 作者認為形式(0x123 == 0x0123)是解釋這種歧義的更好方法。額外的資訊(例如,指定 0x0123 或 0x1230,或指定這只是一個 12-bit 數字)可以解決這個問題。 - RFC2367 2.4 Illustration of Message Layout 下面顯示了八位元組在 PF_KEY 資訊中表示的方式。Optional 字段也是這樣表示。 base header: ![base header](https://i.imgur.com/RikilTM.png) 根據各種基本表頭字段的值,基本表頭之後可以跟隨一個或多個以下擴展字段。以下字段是有序的,如果它們出現,它們應該按照下面顯示的順序出現。 擴展字段不得重複。如果存在必須重複擴展的情況,應引起作者的注意。 **The Association extension** ![The Association extension](https://i.imgur.com/5teC4dF.png) **The Lifetime extension** ![The Lifetime extension](https://i.imgur.com/GXhFEEw.png) ![The Lifetime extension](https://i.imgur.com/jSoA8zl.png) **The Address extension** ![The Address extension](https://i.imgur.com/xSs2gVY.png) **The Key extension** ![The Key extension](https://i.imgur.com/7f9yuKi.png) **The Identity extension** ![The Identity extension](https://i.imgur.com/wLaCQ3N.png) **The Sensitivity extension** ![The Sensitivity extension](https://i.imgur.com/rictsPG.png) **The Proposal extension** ![The Proposal extension](https://i.imgur.com/rC5vfUY.png) ![The Proposal extension](https://i.imgur.com/y15vq2W.png) **The Supported Algorithms extension** ![The Supported Algorithms extension](https://i.imgur.com/I38lPUP.png) **The SPI Range extension** ![The SPI Range extension](https://i.imgur.com/GMc2zVh.png)

Import from clipboard

Paste your markdown or webpage here...

Advanced permission required

Your current role can only read. Ask the system administrator to acquire write and comment permission.

This team is disabled

Sorry, this team is disabled. You can't edit this note.

This note is locked

Sorry, only owner can edit this note.

Reach the limit

Sorry, you've reached the max length this note can be.
Please reduce the content or divide it to more notes, thank you!

Import from Gist

Import from Snippet

or

Export to Snippet

Are you sure?

Do you really want to delete this note?
All users will lose their connection.

Create a note from template

Create a note from template

Oops...
This template has been removed or transferred.
Upgrade
All
  • All
  • Team
No template.

Create a template

Upgrade

Delete template

Do you really want to delete this template?
Turn this template into a regular note and keep its content, versions, and comments.

This page need refresh

You have an incompatible client version.
Refresh to update.
New version available!
See releases notes here
Refresh to enjoy new features.
Your user state has changed.
Refresh to load new user state.

Sign in

Forgot password

or

By clicking below, you agree to our terms of service.

Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
Wallet ( )
Connect another wallet

New to HackMD? Sign up

Help

  • English
  • 中文
  • Français
  • Deutsch
  • 日本語
  • Español
  • Català
  • Ελληνικά
  • Português
  • italiano
  • Türkçe
  • Русский
  • Nederlands
  • hrvatski jezik
  • język polski
  • Українська
  • हिन्दी
  • svenska
  • Esperanto
  • dansk

Documents

Help & Tutorial

How to use Book mode

Slide Example

API Docs

Edit in VSCode

Install browser extension

Contacts

Feedback

Discord

Send us email

Resources

Releases

Pricing

Blog

Policy

Terms

Privacy

Cheatsheet

Syntax Example Reference
# Header Header 基本排版
- Unordered List
  • Unordered List
1. Ordered List
  1. Ordered List
- [ ] Todo List
  • Todo List
> Blockquote
Blockquote
**Bold font** Bold font
*Italics font* Italics font
~~Strikethrough~~ Strikethrough
19^th^ 19th
H~2~O H2O
++Inserted text++ Inserted text
==Marked text== Marked text
[link text](https:// "title") Link
![image alt](https:// "title") Image
`Code` Code 在筆記中貼入程式碼
```javascript
var i = 0;
```
var i = 0;
:smile: :smile: Emoji list
{%youtube youtube_id %} Externals
$L^aT_eX$ LaTeX
:::info
This is a alert area.
:::

This is a alert area.

Versions and GitHub Sync
Get Full History Access

  • Edit version name
  • Delete

revision author avatar     named on  

More Less

Note content is identical to the latest version.
Compare
    Choose a version
    No search result
    Version not found
Sign in to link this note to GitHub
Learn more
This note is not linked with GitHub
 

Feedback

Submission failed, please try again

Thanks for your support.

On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

Please give us some advice and help us improve HackMD.

 

Thanks for your feedback

Remove version name

Do you want to remove this version name and description?

Transfer ownership

Transfer to
    Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

      Link with GitHub

      Please authorize HackMD on GitHub
      • Please sign in to GitHub and install the HackMD app on your GitHub repo.
      • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
      Learn more  Sign in to GitHub

      Push the note to GitHub Push to GitHub Pull a file from GitHub

        Authorize again
       

      Choose which file to push to

      Select repo
      Refresh Authorize more repos
      Select branch
      Select file
      Select branch
      Choose version(s) to push
      • Save a new version and push
      • Choose from existing versions
      Include title and tags
      Available push count

      Pull from GitHub

       
      File from GitHub
      File from HackMD

      GitHub Link Settings

      File linked

      Linked by
      File path
      Last synced branch
      Available push count

      Danger Zone

      Unlink
      You will no longer receive notification when GitHub file changes after unlink.

      Syncing

      Push failed

      Push successfully