以下根据strongswan代码中的testing/tests/ikev2/net2net-rekey/中的测试环境,验证一下网络到网络的IKEv2协议的秘钥重协商过程。拓扑结构如下:

拓扑图中使用到的设备包括:虚拟网关moon和sun。

moon网关配置

moon网关的配置文件:/etc/ipsec.conf ,内容如下。为了进行秘钥重协商,安全关联的生存期lifetime指定为较短的10s,正常情况下不应使用如此短的时间值。margintime指定在具体生存期到期之前多久开始进行重新协商,此处为5s秒,即在距离到期(10s)前5s开始重协商。rekeyfuzz字段的值为0%表示禁用重协商时间的随机功能。

conn %defaultikelifetime=60mlifetime=10smargintime=5srekeyfuzz=0%keyingtries=1keyexchange=ikev2mobike=noconn net-netleft=PH_IP_MOONleftcert=moonCert.pemleftid=@moon.strongswan.orgleftsubnet=10.1.0.0/16leftfirewall=yesright=PH_IP_SUNrightid=@sun.strongswan.orgrightsubnet=10.2.0.0/16auto=add

strongswan使用以下的公式计算重协商发起时间,根据以上的参数配置,可得到rekeytime为5秒。rekeyfuzz默认为100%。

rekeytime = lifetime - (margintime + random(0, margintime * rekeyfuzz))

文件strongswan-5.8.1/src/libcharon/plugins/stroke/stroke_socket.c中的函数stroke_add_conn处理连接配置的添加,例如添加以上的net-net连接。

static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
{this->config->add(this->config, msg);this->attribute->add_dns(this->attribute, msg);this->handler->add_attributes(this->handler, msg);

以上add函数指针指向同目录下文件stroke_config.c文件中的add函数,其中调用子函数build_peer_cfg处理秘钥重协商相关参数。jitter_time变量的值正是依照以上rekeyfuzz配置项的值与margintime值的乘积而得到的一个范围值。此值范围为[0,margintime]。peer.rekey_time的值初始化为生存期lifetime的值减去over_time(margintime)的值。

static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this, stroke_msg_t *msg, ike_cfg_t *ike_cfg)
{peer.jitter_time = msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100;peer.over_time = msg->add_conn.rekey.margin;if (msg->add_conn.rekey.reauth){       peer.reauth_time = msg->add_conn.rekey.ike_lifetime - peer.over_time;} else {peer.rekey_time = msg->add_conn.rekey.ike_lifetime - peer.over_time;}

在文件libcharon/config/peer_cfg.c中的函数get_rekey_time用于获取秘钥重协商的时间,如下所示,为以上计算的rekey_time时间,加上[0,margintime]范围内的随机时间。另外,对于IKE连接的重新认证时间,margintime和rekeyfuzz配置参数同样有效,参见get_reauth_time函数。

METHOD(peer_cfg_t, get_rekey_time, uint32_t, private_peer_cfg_t *this, bool jitter)
{if (this->rekey_time == 0){return 0;}if (this->jitter_time == 0 || !jitter){return this->rekey_time;}return this->rekey_time - (random() % this->jitter_time);

moon网关的配置文件:/etc/strongswan.conf,内容如下。字段delete_rekeyed_delay值为2,意味着在秘钥重协商完成之后,延时2秒钟删除CHILD_SA子关联的inbound方向结构,以便能够处理延迟接收到的报文。此值配置为0,将等待CHILD_SA超时执行删除。

charon {load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac stroke kernel-netlink socket-default updown# remove rekeyed inbound SA a bit quicker for the test scenariodelete_rekeyed_delay = 2syslog {daemon {knl = 2}}
}

在文件:strongswan-5.8.1/src/libcharon/sa/ikev2/tasks/child_delete.c中,函数destroy_and_reestablish负责删除CHILD_SA子关联。首先获得配置的delete_rekeyed_delay字段的值,如果未配置,使用默认值DELETE_REKEYED_DELAY(5秒)。再者对于秘钥重协商的SA,移除其outbond方向SA。最后,如果当前时间加上delay延时时间小于SA的生存期,延迟delay之后调用函数delete_child_sa_job_create_id删除inbound方向SA。

static status_t destroy_and_reestablish(private_child_delete_t *this)
{delay = lib->settings->get_int(lib->settings, "%s.delete_rekeyed_delay",DELETE_REKEYED_DELAY, lib->ns);enumerator = this->child_sas->create_enumerator(this->child_sas);while (enumerator->enumerate(enumerator, (void**)&entry)){child_sa = entry->child_sa;child_sa->set_state(child_sa, CHILD_DELETED);/* signal child down event if we weren't rekeying */protocol = child_sa->get_protocol(child_sa);if (!entry->rekeyed) { ... }else{install_outbound(this, protocol, child_sa->get_rekey_spi(child_sa));/* for rekeyed CHILD_SAs we uninstall the outbound SA but don't* immediately destroy it, by default, so we can process delayed packets */child_sa->remove_outbound(child_sa);expire = child_sa->get_lifetime(child_sa, TRUE);if (delay && (!expire || ((now + delay) < expire))){lib->scheduler->schedule_job(lib->scheduler,(job_t*)delete_child_sa_job_create_id(child_sa->get_unique_id(child_sa)), delay);continue;}

sun网关配置

sun的配置文件:/etc/ipsec.conf,内容如下。无需要注意的特殊配置项。

conn %defaultikelifetime=60mkeylife=20mrekeymargin=3mkeyingtries=1keyexchange=ikev2mobike=noconn net-netleft=PH_IP_SUNleftcert=sunCert.pemleftid=@sun.strongswan.orgleftsubnet=10.2.0.0/16leftfirewall=yesright=PH_IP_MOONrightid=@moon.strongswan.orgrightsubnet=10.1.0.0/16auto=add

连接建立

操作流程如下,在sun和moon两个网关上启动strongswan进程,之后在moon网关上发起net-net连接的建立。

sun::ipsec start
moon::ipsec start
sun::expect-connection net-net
moon::expect-connection net-net
moon::ipsec up net-net

内核SA过期

moon网关的内核的SA如下所示,可见在192.168.0.2到192.168.0.1反向的SA的软性超时时长为5秒钟,硬性时长为10秒钟,由配置一致。

src 192.168.0.1 dst 192.168.0.2proto esp spi 0xc14f1c0a(3243187210) reqid 1(0x00000001) mode tunnellifetime config:expire add: soft 0(sec), hard 10(sec)expire use: soft 0(sec), hard 0(sec)lifetime current:168(bytes), 2(packets)add 2019-12-09 09:44:21 use 2019-12-09 09:44:22stats:replay-window 0 replay 0 failed 0
src 192.168.0.2 dst 192.168.0.1proto esp spi 0xcb131d54(3407027540) reqid 1(0x00000001) mode tunnellifetime config:expire add: soft 5(sec), hard 10(sec)expire use: soft 0(sec), hard 0(sec)lifetime current:168(bytes), 2(packets)add 2019-12-09 09:44:21 use 2019-12-09 09:44:22

内核中结构体类型变量netlink_mgr初始化了notify函数调用xfrm_send_state_notify用于向应用层发送netlink消息通知,如下所示。

static struct xfrm_mgr netlink_mgr = {.notify     = xfrm_send_state_notify,.acquire    = xfrm_send_acquire,.compile_policy = xfrm_compile_policy,.notify_policy  = xfrm_send_policy_notify,.report     = xfrm_send_report,.migrate    = xfrm_send_migrate,.new_mapping    = xfrm_send_mapping,.is_alive   = xfrm_is_alive,
};

函数xfrm_send_state_notify内容如下,对于SA过期消息XFRM_MSG_EXPIRE,由函数xfrm_exp_state_notify处理。

static int xfrm_send_state_notify(struct xfrm_state *x, const struct km_event *c)
{switch (c->event) {case XFRM_MSG_EXPIRE:return xfrm_exp_state_notify(x, c);

在函数xfrm_exp_state_notify中,创建netlink消息报文skb,由子函数build_expire填充内容,最后,xfrm_nlmsg_multicast将消息多播发送到组XFRMNLGRP_EXPIRE。

static int xfrm_exp_state_notify(struct xfrm_state *x, const struct km_event *c)
{struct net *net = xs_net(x);struct sk_buff *skb;skb = nlmsg_new(xfrm_expire_msgsize(), GFP_ATOMIC);if (skb == NULL)return -ENOMEM;if (build_expire(skb, x, c) < 0) {kfree_skb(skb);return -EMSGSIZE;}return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_EXPIRE);

目前发送到应用层的消息中包括portid,以及表明时硬性过期还是软性过期的hard值,SA的标记mark和xfrm虚拟接口索引if_id值。

static int build_expire(struct sk_buff *skb, struct xfrm_state *x, const struct km_event *c)
{struct xfrm_user_expire *ue;struct nlmsghdr *nlh;nlh = nlmsg_put(skb, c->portid, 0, XFRM_MSG_EXPIRE, sizeof(*ue), 0);ue = nlmsg_data(nlh);copy_to_user_state(x, &ue->state);ue->hard = (c->data.hard != 0) ? 1 : 0;/* clear the padding bytes */memset(&ue->hard + 1, 0, sizeof(*ue) - offsetofend(typeof(*ue), hard));err = xfrm_mark_put(skb, &x->mark);err = xfrm_if_id_put(skb, x->if_id);

内核函数km_state_expired将调用以上netlink_mgr结构中的notify指针,事件类型为XFRM_MSG_EXPIRE。

void km_state_notify(struct xfrm_state *x, const struct km_event *c)
{       struct xfrm_mgr *km;rcu_read_lock();list_for_each_entry_rcu(km, &xfrm_km_list, list)if (km->notify)km->notify(x, c);rcu_read_unlock();
}
void km_state_expired(struct xfrm_state *x, int hard, u32 portid)
{   struct km_event c;c.data.hard = hard;c.portid = portid;   c.event = XFRM_MSG_EXPIRE;km_state_notify(x, &c);

内核SA定时器

内核在分配SA结构xfrm_state时,初始化mtimer定时器,处理函数为xfrm_timer_handler。

struct xfrm_state *xfrm_state_alloc(struct net *net)
{struct xfrm_state *x;x = kmem_cache_alloc(xfrm_state_cache, GFP_ATOMIC | __GFP_ZERO);if (x) {tasklet_hrtimer_init(&x->mtimer, xfrm_timer_handler,CLOCK_BOOTTIME, HRTIMER_MODE_ABS);x->curlft.add_time = ktime_get_real_seconds();

随后在xfrm_state_add(__xfrm_state_insert)函数或者xfrm_state_update函数中,将启动此定时器。

static void __xfrm_state_insert(struct xfrm_state *x)
{tasklet_hrtimer_start(&x->mtimer, ktime_set(1, 0), HRTIMER_MODE_REL);

以下的超时处理函数xfrm_timer_handler,如果为软性过期,将调用km_state_expired发送SA过期消息。

static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me)
{struct tasklet_hrtimer *thr = container_of(me, struct tasklet_hrtimer, timer);struct xfrm_state *x = container_of(thr, struct xfrm_state, mtimer);time64_t now = ktime_get_real_seconds();if (x->lft.soft_add_expires_seconds) {long tmo = x->lft.soft_add_expires_seconds + x->curlft.add_time - now;if (tmo <= 0) {warn = 1;x->xflags &= ~XFRM_SOFT_EXPIRE;} else if (tmo < next) {next = tmo;x->xflags |= XFRM_SOFT_EXPIRE;x->saved_tmo = tmo;}}x->km.dying = warn;if (warn)km_state_expired(x, 0, 0);

成员变量soft_add_expires_seconds的值在xfrm_state的构建函数xfrm_state_construct中,由子函数copy_from_user_state从应用层的数据结构xfrm_usersa_info->lft中拷贝而来。x->curlft.add_time的值在xfrm_state结构的分配函数xfrm_state_alloc中配赋予当前的值。

static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
{memcpy(&x->id, &p->id, sizeof(x->id));memcpy(&x->sel, &p->sel, sizeof(x->sel));memcpy(&x->lft, &p->lft, sizeof(x->lft));

在strongswan文件strongswan-5.8.1/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c中,函数add_sa初始化了xfrm_lifetime_cfg结构相关的成员变量。其中soft_add_expires_seconds初始化为rekey的时长,而hard_add_expires_seconds初始化为lifttime的时长。

METHOD(kernel_ipsec_t, add_sa, status_t, private_kernel_netlink_ipsec_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_add_sa_t *data)
{/* we use lifetimes since added, not since used */sa->lft.soft_add_expires_seconds = data->lifetime->time.rekey;sa->lft.hard_add_expires_seconds = data->lifetime->time.life;sa->lft.soft_use_expires_seconds = 0;sa->lft.hard_use_expires_seconds = 0;

秘钥重协商

文件strongswan-5.8.1/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c中的函数process_expire接收处理内核的安全关联到期消息XFRM_MSG_EXPIRE。其调用内核接口的expire函数指针进行处理。

/** Process a XFRM_MSG_EXPIRE from kernel */
static void process_expire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr)
{struct xfrm_user_expire *expire;expire = NLMSG_DATA(hdr);protocol = expire->state.id.proto;spi = expire->state.id.spi;DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE");if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH){dst = xfrm2host(expire->state.family, &expire->state.id.daddr, 0);if (dst){charon->kernel->expire(charon->kernel, protocol, spi, dst, expire->hard != 0);dst->destroy(dst);

如下为内核接口结构kernel_interface_t的expire函数,其中调用注册在内核接口上的所有listener结构的expire成员函数。

METHOD(kernel_interface_t, expire, void, private_kernel_interface_t *this, uint8_t protocol, uint32_t spi, host_t *dst, bool hard)
{kernel_listener_t *listener;enumerator_t *enumerator;this->mutex->lock(this->mutex);enumerator = this->listeners->create_enumerator(this->listeners);while (enumerator->enumerate(enumerator, &listener)){if (listener->expire && !listener->expire(listener, protocol, spi, dst, hard)) {this->listeners->remove_at(this->listeners, enumerator);}

文件strongswan-5.8.1/src/libcharon/kernel/kernel_handler.c中函数kernel_handler_create注册了listener结构,用于处理安全关联的到期事件,其中的expire函数如下,由函数rekey_child_sa_job_create处理SA的秘钥重协商。

METHOD(kernel_listener_t, expire, bool, private_kernel_handler_t *this, uint8_t protocol, uint32_t spi, host_t *dst, bool hard)
{protocol_id_t proto = proto_ip2ike(protocol);DBG1(DBG_KNL, "creating %s job for CHILD_SA %N/0x%08x/%H", hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), dst);if (hard) {lib->processor->queue_job(lib->processor,(job_t*)delete_child_sa_job_create(proto, spi, dst, hard));} else {lib->processor->queue_job(lib->processor,(job_t*)rekey_child_sa_job_create(proto, spi, dst));}

文件strongswan-5.8.1/src/libcharon/processing/jobs/rekey_child_sa_job.c中函数execute为rekey_child_sa_job的执行函数。首先根据protocol,spi和dst三个参数获取到对应的ike_sa结构;接下来,执行ike_sa结构的rekey_child_sa函数。

METHOD(job_t, execute, job_requeue_t, private_rekey_child_sa_job_t *this)
{ike_sa_t *ike_sa;ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager, this->protocol, this->spi, this->dst, NULL);if (ike_sa == NULL){DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for rekey", protocol_id_names, this->protocol, htonl(this->spi), this->dst);}else{if (ike_sa->get_state(ike_sa) != IKE_PASSIVE){ike_sa->rekey_child_sa(ike_sa, this->protocol, this->spi);}charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);}

以下为文件strongswan-5.8.1/src/libcharon/sa/ike_sa.c中的函数rekey_child_sa,其调用task_manager_t结构的两个指针函数:queue_child_rekey和initiate。

METHOD(ike_sa_t, rekey_child_sa, status_t, private_ike_sa_t *this, protocol_id_t protocol, uint32_t spi)
{if (this->state == IKE_PASSIVE){return INVALID_STATE;}this->task_manager->queue_child_rekey(this->task_manager, protocol, spi);return this->task_manager->initiate(this->task_manager);

文件strongswan-5.8.1/src/libcharon/sa/ikev2/task_manager_v2.c中函数queue_child_rekey如下。其新增了一个任务task,此任务由函数child_rekey_create创建。

METHOD(task_manager_t, queue_child_rekey, void, private_task_manager_t *this, protocol_id_t protocol, uint32_t spi)
{              queue_task(this, (task_t*)child_rekey_create(this->ike_sa, protocol, spi));

以上任务的实现位于文件strongswan-5.8.1/src/libcharon/sa/ikev2/tasks/child_rekey.c中,在函数child_rekey_create中依据protocol的值为连接的initiator或者responder初始化任务的build和process函数指针。对于此处的moon网关,由于是连接的发起方,使用build_i和process_i函数。

child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol, uint32_t spi)
{private_child_rekey_t *this;INIT(this,.public = {.task = {.get_type = _get_type,.migrate = _migrate,.destroy = _destroy,},},.ike_sa = ike_sa,.protocol = protocol,.spi = spi,);if (protocol != PROTO_NONE){       this->public.task.build = _build_i;this->public.task.process = _process_i;this->initiator = TRUE;this->child_create = NULL;

看一下在同一个文件中的函数build_i,首先需要获取到需要重协商秘钥的子SA,如果inbound没有找到,再次由outbound方向进行查找,但是由于使用inbound方向进行rekey操作,在oubound方向找到SA之后,进一步查找inbound方向的spi。其次,如果没有获得到SA结构,意味值其已经不存在了;或者,此SA结构的状态不是CHILD_INSTALLED;再或者,此rekey任务已经有了child_create_t结构,即已经开启过重协商任务,但是其SA的状态又不等于CHILD_REKEYING,表明出现了错误,以上任一情况都结束函数,不在进行后续处理。

METHOD(task_t, build_i, status_t, private_child_rekey_t *this, message_t *message)
{notify_payload_t *notify;uint32_t reqid;child_cfg_t *config;this->child_sa = this->ike_sa->get_child_sa(this->ike_sa, this->protocol, this->spi, TRUE);if (!this->child_sa){       /* check if it is an outbound CHILD_SA */this->child_sa = this->ike_sa->get_child_sa(this->ike_sa, this->protocol, this->spi, FALSE);if (this->child_sa) {/* we work only with the inbound SPI */this->spi = this->child_sa->get_spi(this->child_sa, TRUE);}}if (!this->child_sa ||(!this->child_create && this->child_sa->get_state(this->child_sa) != CHILD_INSTALLED) ||(this->child_create && this->child_sa->get_state(this->child_sa) != CHILD_REKEYING)){/* CHILD_SA is gone or in the wrong state, unable to rekey */message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED);return SUCCESS;}config = this->child_sa->get_config(this->child_sa);

以下为正常的流程,在rekey任务结构中创建一个child_create_t结构,用于完成大部分重协商工作,此处继续使用上一次协商的DH组参数。以及继续使用reqid、mark和if_id值。之后,由刚刚创建的child_create_t结构中的任务函数build来完成rekey工作,其位于文件strongswan-5.8.1/src/libcharon/sa/ikev2/tasks/child_create.c中。另外,将在CREATE_CHILD_SA消息中增加REKEY_SA类型的通知(PLV2_NOTIFY)载荷。函数最后,将此SA的状态更新为CHILD_REKEYING。

        /* our CHILD_CREATE task does the hard work for us */if (!this->child_create) {proposal_t *proposal;uint16_t dh_group;this->child_create = child_create_create(this->ike_sa, config->get_ref(config), TRUE, NULL, NULL);proposal = this->child_sa->get_proposal(this->child_sa);if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &dh_group, NULL)){       /* reuse the DH group negotiated previously */this->child_create->use_dh_group(this->child_create, dh_group);}}reqid = this->child_sa->get_reqid(this->child_sa);this->child_create->use_reqid(this->child_create, reqid);this->child_create->use_marks(this->child_create, this->child_sa->get_mark(this->child_sa, TRUE).value,this->child_sa->get_mark(this->child_sa, FALSE).value);this->child_create->use_if_ids(this->child_create, this->child_sa->get_if_id(this->child_sa, TRUE),this->child_sa->get_if_id(this->child_sa, FALSE));if (this->child_create->task.build(&this->child_create->task, message) != NEED_MORE) {schedule_delayed_rekey(this);message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED);return SUCCESS;}if (message->get_exchange_type(message) == CREATE_CHILD_SA) {/* don't add the notify if the CHILD_CREATE task changed the exchange */notify = notify_payload_create_from_protocol_and_type(PLV2_NOTIFY, this->protocol, REKEY_SA);notify->set_spi(notify, this->spi);message->add_payload(message, (payload_t*)notify);}this->child_sa->set_state(this->child_sa, CHILD_REKEYING);

同一个文件中的函数process_i处理rekey过程中的报文交互,可见其主要由child_create_t结构中的task任务处理rekey消息,最后,由child_delete_create负责删除之前的CHILD_SA。

METHOD(task_t, process_i, status_t, private_child_rekey_t *this, message_t *message)
{if (this->child_create->task.process(&this->child_create->task, message) == NEED_MORE) {/* bad DH group while rekeying, retry, or failure requiring deletion */return NEED_MORE;}/* rekeying done, delete the obsolete CHILD_SA using a subtask */this->child_delete = child_delete_create(this->ike_sa, protocol, spi, FALSE);this->public.task.build = (status_t(*)(task_t*,message_t*))build_i_delete;this->public.task.process = (status_t(*)(task_t*,message_t*))process_i_delete;

函数build_i_delete负责创建INFORMATIONAL类型的删除消息,通知对端删除指定的SA。

static status_t build_i_delete(private_child_rekey_t *this, message_t *message)
{/* update exchange type to INFORMATIONAL for the delete */message->set_exchange_type(message, INFORMATIONAL);return this->child_delete->task.build(&this->child_delete->task, message);

文件strongswan-5.8.1/src/libcharon/sa/ikev2/tasks/child_delete.c中的函数build_i负责创建CHILD_SA的DELETE消息。

METHOD(task_t, build_i, status_t, private_child_delete_t *this, message_t *message)
{INIT(entry,.child_sa = child_sa,.rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYED,);this->child_sas->insert_last(this->child_sas, entry);log_children(this);build_payloads(this, message);

在接收到对端的响应之后,调用函数destroy_and_reestablish删除SA。在此函数中根据配置的delete_rekeyed_delay的值,执行一定的延迟操作。

METHOD(task_t, process_i, status_t, private_child_delete_t *this, message_t *message)
{process_payloads(this, message);DBG1(DBG_IKE, "CHILD_SA closed");return destroy_and_reestablish(this);

报文流程

以下为报文交互流程:

其中MID等于2的两条CREATE_CHILD_SA消息为rekey消息,其中设置了REKEY_SA通知载荷:

最后MID等于3的两条消息,用于删除之前的SA连接。

strongswan版本: 5.8.1
内核版本: 5.0

END

IKEv2子网之间秘钥重协商相关推荐

  1. ECDH秘钥协商算法原理(ECDH Key Exchange)

    ECDH全称是椭圆曲线迪菲-赫尔曼秘钥交换(Elliptic Curve Diffie–Hellman key Exchange),主要是用来在一个不安全的通道中建立起安全的共有加密资料,一般来说交换 ...

  2. ras私钥c#转java_Java与C#秘钥之间的转换

    C#的秘钥与Java秘钥的区别 C#使用的是标准的RSA格式,然后将其中的数字base64编码后,生成XML进行存储. Java中使用的是pkcs8.X.509的公私钥语法,存储的都是相应的JAVA类 ...

  3. java ecdh秘钥交换,ECDH密钥协商算法

    ECDH是EC是"elliptic curves"的意思,DH是"Diffie-Hellman"的意思.它实际上是密钥协商算法,而不是加解密算法. 该算法可以用 ...

  4. NR 5G 安全与秘钥简述

    基本说明 适用于连接到5GC安全的NR: 1.对于用户数据(DRB),加密提供用户数据机密性,完整性保护提供用户数据完整性; 2.对于RRC信令(SRB),加密提供信令数据机密性和完整性保护信令数据完 ...

  5. git 查看自己秘钥_git秘钥配置--转

    git是分布式的代码管理工具,远程的代码管理是基于ssh的,所以要使用远程的git则需要ssh的配置. github的ssh配置如下: 一 . 设置git的user name和email: $ git ...

  6. 主密钥,传输秘钥,工作秘钥

    一.工作密钥 1.概念 工作秘钥也称为数据密钥,包含PIN秘钥,MAC秘钥以及磁道秘钥(TDK).在POS每次做签到交易时,由POS中心下发给POS.需要经常性地定期更换,通常每天更换一次. 在联机更 ...

  7. 动态秘钥分发(基于PKI)的方案论文详读

    1. 题目解析 题目动态秘钥分发由来: 分发方式:车辆从其最近的路侧单元动态地请求钥匙. 该请求通过网络基础结构安全地传播,以到达CA云,并返回密钥: 从分发方式中我们可以知道这是一种动态请求从CA中 ...

  8. 秘钥加密码的登录模式

    应用场景:有时候我们要给远在北京或者国外的开发人员服务器的权限,为了保证服务器的安全性我们不想让他们知道服务器的root登陆密码,所以我们可以给他们用秘钥加密码的登陆模式. 原理:公钥加密 私钥解密. ...

  9. 利用OpenSSH实现基于秘钥的认证

    利用OpenSSH实现基于秘钥的认证 SSH协议介绍:     SSH是Secure Shell的缩写,意思是安全的shell          目前版本有 ssh v1和ssh  v2:在目前工作中 ...

  10. Trustzone——利用硬件对数据加密,秘钥存在芯片里

    我是看 https://zhuanlan.zhihu.com/p/26441212 这个文章知道trustzone自身会存储秘钥,这个秘钥可以来自用户指纹,也可以来自云端下发的key. Truztzo ...

最新文章

  1. C++实现字符串和整数之间的相互转换
  2. 推荐陈永真著作《高效率开关电源设计与制作》
  3. 如何在Oracle11中配置st_shapelib
  4. Git——[error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054]解决方案
  5. mysql 亿级_mysql 亿级数据量 ( sum ,group by )的优化
  6. ajax、jsonp简单封装
  7. 【开源程序(C++)】获取bing图片并自动设置为电脑桌面背景
  8. postgreSQl pathman 用法语句总结
  9. android 文件流转换为zip文件_PDF文件如何转换为TXT文本?教您一招高效转换的方法...
  10. Day-04 基础数据类型list, tuple
  11. 我的世界java版海底神殿种子_我的世界海底神殿种子
  12. CFA一级知识点总结
  13. python运行脚本文件的3种方法
  14. linux下桌面快捷方式无法打开,亲测可用:Linux下桌面快捷方式创建实例
  15. 微信小程序布局 头尾固定中间自适应
  16. 【CS224n】(lecture9)Transformer的变体
  17. 灰狼算法GWO优化径向基网络做回归预测,多输入单输出模型。GWO-RBF
  18. Java面试题:关于sleep()和write()的简答题
  19. 顶级管理思维-发现缺口
  20. php微信地图定位导航,网页拉取微信内置地图(openLocation)详细教程 轻松实现一键导航 – 蓝洛水深...

热门文章

  1. OC:跟随小码哥一起学习KVC
  2. 脉冲计数器校准配置方案
  3. ubuntu16.04 安装 NVIDIA 显卡驱动 +cuda9.0+cudnn +tensorflow AND问题若干
  4. 网络安全涉及到的知识积累(1)
  5. neural networks logistic regression 神经网络逻辑回归
  6. 爬虫 (6)- Scrapy 实战案例 - 爬取不锈钢的相关钢卷信息
  7. linux服务器如何查看mac地址,linux如何查看mac地址_查看mac地址 linux_linux查看mac地址...
  8. 纹波测试方法(收集整理)
  9. Ubuntu 15.10 x64 安装 Android SDK
  10. ubuntu16.04升级18.04时问题, (appstreamcli:5132): GLib-CRITICAL **: g_strchomp: assertion 'string != NULL'