keystone认证方式:UUID、PKI、Fernet;

知识点复习:

通俗的讲,token 是用户的一种凭证,需拿正确的用户名/密码向 Keystone 申请才能得到。如果用户每次都采用用户名/密码访问 OpenStack API,容易泄露用户信息,带来安全隐患。所以 OpenStack 要求用户访问其 API 前,必须先获取 token,然后用 token 作为用户凭据访问 OpenStack API。

公开密钥加密,也称为非对称加密(asymmetric cryptography,加密密钥和解密密钥不相同),在这种密码学方法中,需要一对密钥,分别为公钥(Public Key)和私钥(Private Key),公钥是公开的,私钥是非公开的,需用户妥善保管。如果把加密和解密的流程当做函数 C(x) 和 D(x),P 和 S 分别代表公钥和私钥,对明文 A 和密文 B 而言,数学的角度上有以下公式:

B = C(A, S)

A = D(B, P)

其中加密函数 C(x), 解密函数 D(x) 以及公钥 P 均是公开的。采用公钥加密的密文只能用私钥解密,采用私钥加密的密文只能用公钥解密。非对称加密广泛运用在安全领域,诸如常见的 HTTPS,SSH 登录等。

数字签名又称为公钥数字签名,首先采用 Hash 函数对消息生成摘要,摘要经私钥加密后称为数字签名。接收方用公钥解密该数字签名,并与接收消息生成的摘要做对比,如果二者一致,便可以确认该消息的完整性和真实性。

(1)UUID认证原理:

当用户需要进行操作时(比如访问nova创建虚拟机),用户拿着有效的用户名/密码先去keystone认证,keystone返回给用户一个token(即UUID)。之后用户进行其他操作(如访问nova),先出示这个token给nova-api,nova收到请求后,就用这个token去向keystone进行请求验证。keystone通过比对token,以及检查token的有效期,判断token的有效性,最后返回给nova结果。

缺陷:每次请求都要经过keystone进行验证,造成性能瓶颈。

1.用户输入用户名密码,发送给keystone。

2.Keystone验证用户名密码,并且生成token(UUID),发送给客户端。

3.客户端缓存UUID token

4.客户端发送具体的执行请求(nova boot)和UUID给keystone。

5.Keystone从http请求中获取token,并检查token是否有效

6.Token有效,处理请求,并返回客户端请求结果

7.Token失效,拒绝客户端请求,返回401。

UUID方式源码分析:

UUID token 是长度固定为 32 Byte 的随机字符串,由 uuid.uuid4().hex 生成。

def _get_token_id(self, token_data):    return uuid.uuid4().hex

生成的样例:144d8a99a42447379ac37f78bf0ef608

(2)PKI认证原理:

在keystone初始化时,keystone生成了CA的公钥CA.pem和私钥CA.key,同时keystone产生了自己的公钥keystone.pub和私钥keystone.key,然后将keystone.pub进行CA的签名,生成keystone.pem。

当用户拿着用户名/密码去keystone认证后,keystone将用户的基本信息通过keystone.key进行加密,并将密文作为token返还给用户。当用户拿着token发送请求时(例如访问nova),nova拿到用户token时,通过事先拿到keystone的证书keystone.pem(这一过程只需要进行一次)进行解密,获取用户信息。

对于用户的token,还需进行token的合法时间,以及token还是否存在进行判断。所以当nova每一次拿到token后还需向keystone询问一次token的失败列表,检查token是否失效。这一过程对于keystone的负载还是相当轻的,所以PKI还是有效解决了keystone性能瓶颈的问题。

小结:OpenStack服务中的每一个API Endpoint都有一份keystone签发的证书,失效列表和根证书。API不用在直接去keystone认证token是否合法,只需要根据keystone的证书和失效列表就可以确定token是否合法。但是这里还是会有每次都需要请求keystone去获取失效列表的操作,不可避免。

PKI的流程,首先需要使用 keystone-manage pki_setup命令生成CA及相关的令牌机制,其代码如下所示:

def _get_token_id(self, token_data):

try:

token_json = jsonutils.dumps(token_data, cls=utils.PKIEncoder)

token_id = str(cms.cms_sign_token(token_json,

CONF.signing.certfile,

CONF.signing.keyfile))   #DEFAULT_TOKEN_DIGEST_ALGORITHM=sha256

其中,‘token_data’是获取的user、role、endpoint、catlog等信息集合,而最重要的语句是cms使用签名生成token的过程:cms_sign_token,使用默认的sha256方式加密,处理过程使用process,进行数据的读取、处理,

process = subprocess.Popen(['openssl', 'cms', '-sign',

'-signer', signing_cert_file_name,

'-inkey', signing_key_file_name,

'-outform', 'PEM',

'-nosmimecap', '-nodetach',

'-nocerts', '-noattr',

'-md', message_digest, ],

stdin=subprocess.PIPE,

stdout=subprocess.PIPE,

stderr=subprocess.PIPE,

close_fds=True)

最后output, err = process.communicate(data) 生成Token-id,这个过程涉及到openssl相关的加密技术。

CMS token一般都超过1600个字节,样例:

(3)Fernet认证原理:

1.user在客户端输入用户名密码,发送给keystone。

2.Keystone验证用户名密码,并且生成token(UUID),发送给客户端。

3.客户端缓存token(UUID)

4.客户端发送具体的执行请求给openstack API

5、OpenStack API向 keystone请求token认证

6.Keystone从http请求中获取token,并检查token是否有效

7.Token有效,处理请求,并返回openstack api请求结果

8.Token失效,拒绝客户端请求,返回401。

当集群运行较长一段时间后,访问其 API 会变得奇慢无比,究其原因在于 Keystone 数据库存储了大量的 token 导致性能太差,解决的办法是经常清理 token。为了避免上述问题,社区提出了Fernet token,fernet 是当前主流推荐的token格式,它采用 cryptography 对称加密库(symmetric cryptography,加密密钥和解密密钥相同) 加密 token,具体由 AES-CBC 加密和散列函数 SHA256 签名。Fernet 是专为 API token 设计的一种轻量级安全消息格式,不需要存储于数据库,减少了磁盘的 IO,带来了一定的性能提升。为了提高安全性,需要采用 Key Rotation 更换密钥。

以上代码表明,token 包含了 user_id,project_id,domain_id,methods,expires_at 等信息,重要的是,它没有 service_catalog,所以 region 的数量并不影响它的大小。self.pack() 最终调用如下代码对上述信息加密:

该token 的大小一般在 200 多 Byte 左右,样例:

gAAAAABWfX8riU57aj0tkWdoIL6UdbViV-632pv0rw4zk9igCZXgC-sKwhVuVb-wyMVC9e5TFc 7uPfKwNlT6cnzLalb3Hj0K3bc1X9ZXhde9C2ghsSfVuudMhfR8rThNBnh55RzOB8YTyBnl9MoQ XBO5UIFvC7wLTh_2klihb6hKuUqB6Sj3i_8

简要叙述一下fernet采用 Key Rotation 更换密钥的原理,默认的轮换长度是3,当以keystone-manage fernet-setup生成密钥时,会看到0、1两个索引表征,这分别是什么意思呢?

在此,需要提一下三个概念:

primary key(主密钥)有且只有一个,名为为x,当前用于加密解密token

secondary key(次次密钥)有x-1个,从Primary退役下来的,用于解密当初它加密过的token

staged key(次密钥)有且只有一个,命名为0,准备下一个rotation时变为Primary key,可以解密token

那么上述0 表示的是staged key,1 表示的是primary key,

primary key相比较另外两种key,它的索引最高,并且可以加密、也可以解密;

staged key 相较于secondary key,它更有机会变为primary key。

AES256加密token,SHA256 HMAC验证完整性,

只要Keystone具有访问这些key的权限,token就不需要在keystone数据库中存储

fernet的数据性能最好,原因是它不需要后端持久化操作(采用 Key Rotation定期 更换密钥,只要Keystone具有访问这些key的权限,更新后的token就不需要在keystone数据库中存储,缓解了数据库负载压力),并且token的认证,使用的是密钥进行解密,能够直接得出token Data的信息,从而进行token的过期认证。它的失败原因,只可能是token过期了,或者是token放到了cache缓存中,但是已经被回收了。归根到底,还是token过期了。

keystone令牌三种生成方式的更多相关文章

  1. java的三种随机数生成方式

    随机数的产生在一些代码中很常用,也是我们必须要掌握的.而java中产生随机数的方法主要有三种: 第一种:new Random() 第二种:Math.random() 第三种:currentTimeMi ...

  2. hibernate笔记--继承映射关系的三种实现方式

    单表继承映射(一张表): 假设我们现在有三个类,关系如下: Person类有两个子类Student和Teacher,并且子类都具有自己独有的属性.这种实体关系在hibernate中可以使用单表的继承映 ...

  3. SP避免Form重复提交的三种方案

    SP避免Form重复提交的三种方案  1) javascript ,设置一个变量,只允许提交一次.   <script language="javascript">  ...

  4. 初学者易上手的SSH-hibernate02 三种查询方式

    在上一章中已经搭建好了一个hibernate的环境,那么这一章我们就使用这个环境来进行基本CRUD.在这之前我们先了解一个东西:主键生成策略.就是当向数据库表中插入记录的时候,这个记录的主键该如何生成 ...

  5. 【转】ABP webapi三种方式

    作者:圣杰 链接:https://www.jianshu.com/p/d14733432dc2 來源:简书 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 1. 引言 上一节我们 ...

  6. (转)理解Keystone的四种Token

    Token 是什么 通俗的讲,token 是用户的一种凭证,需拿正确的用户名/密码向 Keystone 申请才能得到.如果用户每次都采用用户名/密码访问 OpenStack API,容易泄露用户信息, ...

  7. nginx限流方案的实现(三种方式)

    通过查看nginx官方文档,小弟查看到了三种nginx限流方式. 1.limit_conn_zone 2.limit_req_zone 3.ngx_http_upstream_module 前两种只能 ...

  8. Secret的三种形式

    Secret ConfigMap这个资源对象是Kubernetes当中非常重要的一个对象,一般情况下ConfigMap是用来存储一些非安全的配置信息,如果涉及到一些安全相关的数据的话用ConfigMa ...

  9. 华为云计算IE面试笔记-FusionSphere Openstack有哪些关键组件,各组件主要功能是什么?三种存储接入组件的差异有哪些?

    1. Nova:在OpenStack环境中提供计算服务,负责计算实例(VM,云主机)生命周期的管理,包括生成.调度和回收.Nova不负责计算实例的告警上报(FC管). 2. Cinder:为计算实例提 ...

随机推荐

  1. Spring的JavaMail实现异步发送邮件

    具体背景就不说了,可以网上搜索相关知识,或者直接看Sping MailSender的官坊网页.这里就直接实战了(Java实现异步发送电子邮件,包含中文无乱码). Maven: <dependen ...

  2. JavaScript -- URL编码

    ----- 010-escape.html ----- <!DOCTYPE html> <html> <head> <meta http-equiv=&quo ...

  3. js便签笔记(5)——Dean Edwards大牛的跨浏览器AddEvent()设计(不知道是不是jQuery事件系统的原型)

    1. 前言: 在看Aaron的jquery源码解读时候,看到事件系统那块,作者提到了Dean Edwards的添加事件的设计,于是就点进去看了看.首先让我吃惊的是,代码非常少,寥寥几十行,非常简单.于 ...

  4. JS中this的那些事儿

    this是JavaScript中最复杂的机制之一.它是一个很特别的关键字,被自动定义在所有函数的作用域中. 一.this到底指向什么? this既不指向函数自身,也不指向函数的词法作用域,具体指向什么 ...

  5. B 树、B+ 树、B* 树

    B 树.B+ 树.B* 树 作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开始谈起,然后论述B+树.B*树,最后谈到R 树.其中B树.B+树及B*树部分由weedge ...

  6. ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(2)

    前言 本节先给大家搭建UI部分,让大家能看到点东西,就好像所有编程书里,开始都是一个Hello World一样 开始搭建 首先建立空白解决方案,我们命名为BYCMS 然后添加新项目BYCMS 我习惯用 ...

  7. [源码]underscore-1.8.3

    // Underscore.js 1.8.3 // http://underscorejs.org // (c) 2009-2015 Jeremy Ashkenas, DocumentCloud an ...

  8. 下拉加载更多DEMO(js实现)

    项目的一个前端页面展示已购买商品时,要求能下拉加载更多.花了点时间研究这个功能,以前没做过. 首先需要给div加scroll事件,监听滚动条滚动动作.那何时触发加载动作呢?当滚动条滚到底的时候.如何判 ...

  9. [Angularjs]cookie操作

    摘要 现在很多app采用内嵌h5的方式进行开发,有些数据会存在webveiw的cookie中,那么如果使用angularjs开发单页应用,就需要用到angularjs的cookie操作.这里提供一个简 ...

  10. MFC框架之线程局部存储

    线程局部存储中用到的API基础:(TLS:Thread Local Storage) 1.在主线程中申请索引 g_index=::TlsAlloc(); 2.在线程函数中使用索引 存值:::TlsSe ...