(turn) understand the four tokens of Keystone

Source: Internet
Author: User
Tags asymmetric encryption

What's Token?

Popularly speaking, token is a user's credential, need to take the correct user name/password to Keystone application to get. If users use username/password to access OpenStack API each time, it is easy to disclose user information, which poses a security risk. So OpenStack requires users to access their APIs before they need to get tokens, and then use token as their user credentials to access the OpenStack API.

The origins of the four tokens

D version, only the UUID type Token,uuid Token is easy to use, but it is easy to give Keystone performance problems, from step 4 of figure one can be seen, each time the OpenStack API receives a user request, you need to verify the Token to Keystone is valid. As the size of the cluster expands, Keystone needs to handle a large number of authentication token requests, which are prone to performance problems under high concurrency.

PKI (public Key infrastructrue) token is used in the G version, compared with the UUID, PKI token carries more user information while also attaching a digital signature to support local authentication, thus avoiding step 4. Because PKI tokens carry more information, including service catalog, as the number of endpoint in OpenStack increases, the number of service catalog carriers is increased, and PKI tokens increase accordingly. It is easy to exceed HTTP Server's allowed maximum HTTP Header (8 KB by default), which causes HTTP requests to fail.

As the name implies, Pkiz token is a compressed version of PKI token, but the compression effect is limited, can not be good processing token size too big problem.

The first three tokens will be persisted in the database, the increasing accumulation of a large number of tokens caused the database performance degradation, so users need to clean up the database token. To avoid this problem, the community presented a Fernet token, which carried a small amount of user information, about 255 Byte, with symmetric encryption and no need to be stored in the database.

Uuid

The UUID token is a random string of length fixed to Byte, generated by Uuid.uuid4 (). Hex.

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

However, because the UUID token does not carry other information, after the OpenStack API receives the token, can not determine whether the token is valid, but also cannot know the user information that the token carries, so we need to check the token by step 4 to Keystone, and obtain User-related information. The sample is as follows:

144d8a99a42447379ac37f78bf0ef608

UUID token is simple and beautiful, does not carry other information, so Keystone must implement token storage and authentication, as the size of the cluster increases, Keystone will become a performance bottleneck.

Pki

Before elaborating on PKI (public key infrastruction) tokens, let's review publicly key cryptography (Public-key cryptography) and digital signatures in a nutshell. Public key encryption, also known as asymmetric encryption (asymmetric cryptography, the encryption key and decryption key is not the same), in this cryptography method, you need a pair of keys, respectively, public key and private key (private key), public key is public, The private key is non-public and requires the user to keep it safe. If the process of encrypting and decrypting is treated as functions C (x) and D (x), P and S represent public and private keys respectively, and for plaintext A and cipher B, the mathematical angle has the following formula:

B = C (A, S)
A = D (B, P)

Where the cryptographic function C (x), the decryption function D (x), and the public key P are all public. Ciphertext with public key encryption can only be decrypted with private key, and ciphertext encrypted with private key can only be decrypted with public key. Asymmetric encryption is widely used in security areas, such as common https,ssh logins.

Digital signature, also known as public key digital signature, first uses the Hash function to generate a digest of the message, the digest is encrypted after the private key is called the digital signature. The receiver decrypts the digital signature with the public key and compares it to the digest generated by the received message, which, if they are consistent, confirms the integrity and authenticity of the message.

The nature of PKI is based on the digital signature, Keystone with the private key to the token digitally signed, each API server with the public key to verify the token locally. The related code is simplified as follows:

def _get_token_id (Self, token_data):     Try :         = Jsonutils.dumps (Token_data, cls=utils. Pkiencoder)        = Str (cms.cms_sign_token (Token_json,                                          CONF.signing.certfile,                                          CONF.signing.keyfile))        return token_id

Where Cms.cms_sign_token calls the OpenSSL CMS--sign to sign the token_data, the Token_data style is as follows:

{  "token": {    "Methods": ["Password" ],    "Roles": [{"ID":"5642056d336b4c2a894882425ce22a86","name":"Admin"}],    "Expires_at":"2015-12-25t09:57:28.404275z",    "Project": {      "Domain": {"ID":"default","name":"Default"},      "ID":"144d8a99a42447379ac37f78bf0ef608","name":"Admin"},    "Catalog": [      {        "Endpoints": [          {            "region_id":"Regionone",            "URL":"http://controller:5000/v2.0",            " Region":"Regionone",            "Interface":" Public",            "ID":"3837de623efd4af799e050d4d8d1f307"          },          ......      ]}],    "Extras": {},    "User": {      "Domain": {"ID":"default","name":"Default"},      "ID":"1552d60a042e4a2caa07ea7ae6aa2f09","name":"Admin"},    "Audit_ids": ["zcvzw2tttgiaasva8qmc3a"],    "Issued_at":"2015-12-25t08:57:28.404304z"  }}

Token_data generated by Cms.cms_sign_token signature token_id is as follows, with a total of 1932 Byte:

MIIKoZIhvcNAQcCoIIFljCCBZICAQExDTALBglghkgBZQMEAgEwggPzBgkqhkiG9w0B......rhr0acV3bMKzmqvViHf-fPVnLDMJajOWSuhimqfLZHRdr+ck0WVQosB6+M6iAvrEF7v
Pkiz

Pkiz on the basis of the PKI to do compression processing, but the effect of compression is extremely limited, in general, the size of the post-compression PKI token of about 90, so pkiz can not be friendly to solve the token size too big problem.

def _get_token_id (Self, token_data):     Try :         = Jsonutils.dumps (Token_data, cls=utils. Pkiencoder)        = Str (cms.pkiz_sign (Token_json,                                     CONF.signing.certfile,                                     CONF.signing.keyfile))         return token_id

Where the following code in Cms.pkiz_sign () calls Zlib to compress the signed message with a compression level of 6.

compressed = zlib.compress(token_id, compression_level=6)

Pkiz token samples For example, a total of 1645 Byte, a decrease of 14.86 compared to PKI tokens:

PKIZ_eJytVcuOozgU3fMVs49aTXhUN0vAQEHFJiRg8IVHgn5OnA149JVaunNS3NYjoSU......W4fRaxrbNtinojheVICXYrEk0oPX6TSnP71IYj2e3nm4MLy7S84PtIPDz4_03IsOb2Q=
Fernet

Users may encounter such a problem, when the cluster has been running for a long time, access to its API will become extremely slow, because the Keystone database stores a large number of tokens resulting in poor performance, the solution is to often clean tokens. To avoid this problem, the community proposed Fernet token, which uses the cryptography symmetric cryptographic library (symmetric cryptography, the same encryption key and decryption key) to encrypt tokens, specifically by the AES-CBC encryption and hashing functions SHA256 signature. Fernet is a lightweight, secure message format designed for API tokens that does not need to be stored in a database, reduces disk IO, and brings some performance gains. To improve security, you need to replace the key with key Rotation.

defCreate_token (self, user_id, Expires_at, Audit_ids, methods=None, domain_id=none, Project_id=none, trust_id=None, Federated_info=None):"""Given a set of payload attributes, generate a Fernet token."""    iftrust_id:version=trustscopedpayload.version Payload=trustscopedpayload.assemble (user_id, methods, project_id, Expires_at, Audit_ids, trust_id) ... versioned_payload= (version,) +Payload Serialized_payload=msgpack.packb (versioned_payload) token=Self.pack (serialized_payload)returnToken

The above code shows that token contains information such as USER_ID,PROJECT_ID,DOMAIN_ID,METHODS,EXPIRES_AT, it is important that it does not have service_catalog, so the number of region does not affect its size. Self.pack () eventually calls the following code to encrypt the above information:

def Crypto (self):     = Utils.load_keys ()    if not keys:        raise  exception. Keysnotfound ()    for in  utils.load_keys ()]    return Fernet. Multifernet (fernet_instances)

The token size is generally around 200 byte, this example style is as follows, the size is 186 Byte:

gAAAAABWfX8riU57aj0tkWdoIL6UdbViV-632pv0rw4zk9igCZXgC-sKwhVuVb-wyMVC9e5TFc7uPfKwNlT6cnzLalb3Hj0K3bc1X9ZXhde9C2ghsSfVuudMhfR8rThNBnh55RzOB8YTyBnl9MoQXBO5UIFvC7wLTh_2klihb6hKuUqB6Sj3i_8
How to choose Token td> symmetric encryption (AES)
Token type UUID PKI pkiz fernet
size + byte KB level KB level approx. 255 Byte
support local authentication not supported support support not supported
Keysto NE load large small small large
stored in database Yes Yes Yes no
carry information none user, Catalog etc user, Catalog, such as user,
involving encryption none Asymmetric encryption Asymmetric Encryption
whether to compress no no Yes no
Version Support D G J K


The choice of Token type involves several factors, including the load on the Keystone server, the number of region, security factors, maintenance costs, and the maturity of the token itself. The number of region affects the size of the Pki/pkiz token, from a security point of view, the UUID does not need to maintain the key, the PKI needs to properly keep the private key on Keystone server, fernet need to change the key periodically, so from the security, maintenance costs and maturity of the view, UUID > Pki/pkiz > Fernet if:

      • Keystone server load is low, region less than 3, using UUID token.
      • Keystone server has a high load and region of less than 3, using Pki/pkiz token.
      • Keystone server has a low load, a region large with or equal to 3, using UUID token.
      • Keystone server load high, region is greater than or equal to 3, K version and above may consider the use of Fernet token.

Http://wsfdl.com/openstack/2015/12/26/%E7%90%86%E8%A7%A3Keystone%E7%9A%84%E5%9B%9B%E7%A7%8DToken.html

2 questions:

Since PKI supports local authentication, why does it still have to be stored in db?

Since the UUID has a valid time, why is it not automatically deleted in db?

(turn) understand the four tokens of Keystone

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.