使用SLS数据加工对JWT数据进行加解密处理

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: Json Web Token是JSON风格轻量级的授权和身份认证规范,可实现无状态、分布式的Web应用授权,它是分布式服务权限控制的标准解决方案。

阿里云日志服务介绍

日志服务(Log Service,简称SLS)是云原生观测与分析平台,为Log、Metric、Trace等数据提供大规模、低成本、实时的平台化服务。日志服务一站式提供数据采集、加工、查询与分析、可视化、告警、消费与投递等功能,全面提升您在研发、运维、运营、安全等场景的数字化能力。

数据加工服务是阿里云SLS推出的面向日志ETL处理的服务,主要解决数据加工过程中转换、过滤、分发、富化等场景。

本文档介绍如何使用DSL对接入到SLS中的JWT数据进行加解密处理,以便快速后续的日志分析等。

JWT是什么

JWT,全称是Json Web Token, 是JSON风格轻量级的授权和身份认证规范,可实现无状态、分布式的Web应用授权,它是分布式服务权限控制的标准解决方案。

SLS中原始数据会存在一些基于JSON Web Token (JWT)标准的数据,需要对其解码,所以有了jwt_encoding函数(编码)和jwt_decoding函数(解码)。这里主要介绍jwt_encoding和jwt_decoding函数。

SLS数据加工jwt处理函数

jwt_encoding

基于JSON Web Token (JWT)标准,对JSON数据进行编码

  • 函数格式

jwt_encoding(payload, key, algorithm="HS256", headers=None)

  • 参数说明

参数名称

参数类型

是否必填

说明

payload

dict

需要进行jwt编码的数据内容,JSON格式。JWT标准定义了7个字段,用户也可以自定义字段:

  • iss (issuer):签发人
  • exp (expiration time):过期时间
  • sub (subject):主题
  • aud (audience):受众
  • nbf (Not Before):生效时间
  • iat (Issued At):签发时间
  • jti (JWT ID):编号


例如:

{

"iss": "user",

"sub": "name",

"aud": "user1",

"some": "payload"

}

key

String

JWT加密密钥(与选定的加密算法相关):

  • 非对称加密算法:PEM格式编码的私钥
  • 对称加密算法:密钥原文

algorithm

String

对令牌进行签名的算法,默认是HS256。

目前支持的算法有:HS256,
HS384,HS512,ES256,
ES256K,ES384,ES512,
RS256,RS384,RS512,
PS256,PS384,PS512,
EdDSA。

headers

dict

JWT编码头信息,默认是

{

"typ": "JWT",

"alg": "HS256"

}

  • 返回结果

返回编码后的字符串。

编码后的数据解释

包含三部分数据:

  1. Header:头部,通常头部有两部分信息:
  • 声明类型type,这里是JWT(type=jwt)
  • 加密算法,自定义(rs256/base64/hs256)

我们会对头部进行base64加密(可解密),得到第一部分数据

  1. Payload:载荷,就是有效数据,一般包含下面信息:
  • 用户身份信息-userid,username(注意,这里因为采用base64加密,可解密,因此不要存放敏感信息)
  • 注册声明:如token的签发时间,过期时间,签发人等
    这部分也会采用base64加密,得到第二部分数据
  1. Signature:base64加密,签名,是整个数据的认证信息。一般根据前两步的数据,再加上服务的的密钥(secret,盐)(不要泄漏,最好周期性更换),通过加密算法生成。用于验证整个数据完整和可靠性。

头部(header)

头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以 被表示成一个JSON对象。如:

{"typ":"JWT", "alg":"HS256"}

这就是头部的明文内容,第一部分说明他是一个jwt,第二部分则指出签名算法用的是HS256算法。

然后将这个头部进行BASE64编码,编码后形成头部:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

载荷(payload)

载荷就是存放有效信息的地方,有效信息包含三个部分:

(1)标准中注册的声明(建议但不强制使用)

  • iss: jwt签发者
  • sub: jwt所面向的用户
  • aud: 接收jwt的一方
  • exp: jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf: 定义在什么时间之前,该jwt都是不可用的.
  • iat: jwt的签发时间
  • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

(2)公共的声明

公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息. 但不建议添加敏感信息,因为该部分在客户端可解密.

(3)私有的声明

私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64 是对称解密的,意味着该部分信息可以归类为明文信息。

如:{

 "sub": "1234567890",

 "name": "John Doe",

 "iat": 1516239022

}

上面就是一个简单的载荷的明文,接下来使用base64加密:

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

签证(signature)

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

  • header (base64后的)
  • payload (base64后的)
  • secret

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第 三部分。

总之,jwt_encoding编码后的数据实际上就是一个字符串,有三部分组成:Header.payload.signature,每部分都是通过base64加密而成的

jwt_decoding

基于JSON Web Token (JWT)标准,将数据解码为原始JSON

  • 函数格式

jwt_decoding(jwt_payload,key="",algorithms=None,options=None,audience=None,issuer=None,leeway=0)

  • 参数说明

参数名称

参数类型

是否必填

说明

jwt_payload

String

需要被解码的jwt。

key

String

JWT加密密钥(与选定的加密算法相关):

  • 非对称加密算法:PEM格式编码的公钥
  • 对称加密算法:密钥原文

algorithms

list

对令牌进行签名的算法,例如 HS256。

options

dict

扩展解码和验证选项。

  • verify_signature:是否验证JWT加密签名,默认为True。
  • require: 编码数据中必须存在的字段,默认为空。例如[“exp”、“iat”、“nbf”]。
  • verify_aud: 是否检查aud字段,默认为True。
  • verify_iss:是否检查iss字段,默认为True。
  • verify_exp:是否检查exp字段,默认为True。
  • verify_iat:是否检查iat字段,默认为True。
  • verify_nbf: 是否检查nbf字段,默认为True。

例如:

{"require": ["aud"], "verify_aud": True}

audience

String/list

用于检查aud的值 ,编码时候设置了'aud'参数,且

options扩展项中设置了"require": ["aud"] 或者"verify_aud": True时,解码就必须设置该参数 。

issuer

String

用于检查iss的值 ,编码时候设置了'iss'参数,且

options扩展项中设置了"require": ["iss"] 或者"verify_iss": True时,解码就必须设置该参数 。

leeway

float

到期检查的时间间隔(以秒为单位)。

应用场景

场景一 使用对称加密算法HS256(HMAC)

原始日志:

data: {"some": "payload"}

加工规则:

e_set("jwt_token", jwt_encoding(v("data"),"secret", algorithm="HS256"))

e_set("data_decoded", jwt_decoding(v("jwt_token"), "secret", algorithms="HS256"))

加工结果:

data:{"some": "payload"}

data_decoded:{"some": "payload"}

jwt_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U

场景二 使用非对称算法RS256(RSA)

原始日志:

data: {"some": "payload"}

加工规则:

e_set("jwt_token", jwt_encoding(v("data"),"-----BEGIN RSA PRIVATE KEY-----\nMIICYQIBAAKBgQC1iaUr5cgShCn0127+w14XN297q/IviaewIeIJsKTZF1hBPsLn\nNIPsnqtQ9DFbjIyqyZvdmQFDJCSLpXaVc648yepnFDKbOfs3r+K4Crnpo2SuZmNV\nNDVEi4pECXlBz810zJY1wqVArM7qGAyCcRLBprwXB6wfEhk3CAP3c29+pwIDAQAB\nAoGAARo65I9arbIbxx7fz7BEDAQMK0YaDGvbltg91S07cw4PPSYybNEG1BMKm01A\nV3v9BrR+u9PIDC5WAnsYwiODqEoSyk8OwO1E2kWA6+MNclYYfVjaJeiRJ5PzCud/\niUObonptRzxuTng+u1oGuX7QwUhwGJdXVBUAtJFYwXR2qVECRQC5S+6vdFESRLSX\n7yBZVM6+49lZcdehMv0HwT17UseLvWcjeSbiogvv02HbYilrW9ZydKsixAWP5w/U\nS3L34CS811VcDQI9APrOiL7c1xg5fX8wAWv2d+e+MfZoB3ohb8671W3pmp3JVnjY\ntzhoYNNQmnmRQQWf7n3J63MQz4sYYNn0gwJEE/pl37Dw1MFnn0H/AOKt79LtKkGl\n+BFhSqbBFDzWmvBu4Fo9oQ3Lr63gzSCGSrb6JhkCIptz5hIJmOARozwdeebVozkC\nPQDwOqVmU3c/P8nB6oRiGditw1Jt1yTaSW6jkOyUc73iRngqFkIgqHGd1kWwDX4/\nWfoAyEhalY6Fh5s1COsCRQCy4b3hnQws5zz/gmGNnoyxn9N+A09ySaFtn2WkUlrR\nZ6DwoJz+n6EgjLY8z6ZQyv342iobO5zKkZHFvO9QYGqk7y8lJA==\n-----END RSA PRIVATE KEY-----\n", algorithm="RS256"))


e_set("data_decoded", jwt_decoding(v("jwt_token"), "-----BEGIN RSA PUBLIC KEY-----\nMIGJAoGBALWJpSvlyBKEKfTXbv7DXhc3b3ur8i+Jp7Ah4gmwpNkXWEE+wuc0g+ye\nq1D0MVuMjKrJm92ZAUMkJIuldpVzrjzJ6mcUMps5+zev4rgKuemjZK5mY1U0NUSL\nikQJeUHPzXTMljXCpUCszuoYDIJxEsGmvBcHrB8SGTcIA/dzb36nAgMBAAE=\n-----END RSA PUBLIC KEY-----\n", algorithms="RS256"))


加工结果:

data:{"some": "payload"}

data_decoded:{"some": "payload"}

jwt_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Ewwls5YPuJCmAR3XR2tcptOLrH83wVCzmUaUpGMzMLcPknRrIvbDmFGlNlQha-PMx0jsxt3t1oxpz7P3z3SR9o4qyWusAb99UG_Jn8oP8W0a5GKSy4UEJB0xgpVvJl5F2JaIPeUSHpV0VeS2WAsGSBBSAaOMkrc-8uie-H4J9M0

场景三 自定义headers内容

原始日志:

data: {"some": "payload"}

加工规则:

e_set("jwt_token", jwt_encoding(v("data"),"secret", algorithm="HS256", headers={"kid": "230498151c214b788dd97f22b85410a5"}))

e_set("data_decoded", jwt_decoding(v("jwt_token"), "secret", algorithms="HS256"))

加工结果:

data:{"some": "payload"}

data_decoded:{"some": "payload"}

jwt_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjIzMDQ5ODE1MWMyMTRiNzg4ZGQ5N2YyMmI4NTQxMGE1In0.eyJzb21lIjoicGF5bG9hZCJ9.gdQ884yjlnLnIrYjfQaClE6rJC2x8v2OP2s_eXOLhZA


场景四 未经验证用户声明

原始日志:

data: {"some": "payload"}

加工规则:

e_set("jwt_token", jwt_encoding(v("data"),"secret", algorithm="HS256"))

e_set("data_decoded", jwt_decoding(v("jwt_token"), options={"verify_signature": False}))

加工结果:

data:{"some": "payload"}

data_decoded:{"some": "payload"}

jwt_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U

场景五 原始数据字段为含有用户声明,验证iat

原始日志:

data: {"some": "payload", "iss": [1, 2], "sub": "name", "nbf": 123,"iat": "22"}

加工规则:

e_set("jwt_token", jwt_encoding(v("data"),"secret"))

e_set("data_decoded", jwt_decoding(v("jwt_token"), "secret",algorithms="HS256",options={"require": ["iat"],"verify_iat": True}))

加工结果:

data:{"some": "payload", "iss": [1, 2], "sub": "name", "nbf": 123,"iat": "22"}

data_decoded:{"some": "payload", "iss": [1, 2], "sub": "name", "nbf": 123, "iat": "22"}

jwt_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCIsImlzcyI6WzEsMl0sInN1YiI6Im5hbWUiLCJuYmYiOjEyMywiaWF0IjoiMjIifQ.2j5Q4Oag1oBBaQYV5GH2bJWrk4f-OKqsGTPvE9q-syQ

场景六  原始数据字段为含有用户声明,验证iss

原始数据:

data:{"some": "payload", "iss": "urn:foo"}

加工规则:

e_set("jwt_token", jwt_encoding(v("data"),"secret"))

e_set("data_decoded", jwt_decoding(v("jwt_token"), "secret",issuer="urn:foo", algorithms=["HS256"]))

加工结果:

data:{"some": "payload", "iss": "urn:foo"}

data_decoded:{"some": "payload", "iss": "urn:foo"}

jwt_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCIsImlzcyI6InVybjpmb28ifQ.KUsdL-cGUBYkqRJTCt1IDxI_YTN4-1CwcZdWkPk1vP8

场景七 原始数据字段为含有用户声明,验证aud

原始日志:

data: {"some": "payload", "aud": ["urn:foo", "urn:bar"]}

加工规则:

e_set("jwt_token", jwt_encoding(v("data"),"secret"))

e_set("data_decoded", jwt_decoding(v("jwt_token"), "secret",audience="urn:foo", algorithms=["HS256"]))

加工结果:

data:{"some": "payload", "aud": ["urn:foo", "urn:bar"]}

data_decoded:{"some": "payload", "aud": ["urn:foo", "urn:bar"]}

jwt_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCIsImF1ZCI6WyJ1cm46Zm9vIiwidXJuOmJhciJdfQ.Xhlfx9T5kTyehePsxKpcD81EB5tZ8sCoMHHP6kSE1v8

其他参考

1、SLS相关说明: https://yuque.antfin-inc.com/slssh/ops/sheke3#Cg08I

2、PyJWT官网:https://pyjwt.readthedocs.io/en/latest/usage.html

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
7天前
|
JSON 安全 数据安全/隐私保护
深度剖析:Python如何运用OAuth与JWT,为数据加上双保险🔐
【10月更文挑战第10天】本文介绍了OAuth 2.0和JSON Web Tokens (JWT) 两种现代Web应用中最流行的认证机制。通过使用Flask-OAuthlib和PyJWT库,详细展示了如何在Python环境中实现这两种认证方式,从而提升系统的安全性和开发效率。OAuth 2.0适用于授权过程,JWT则简化了认证流程,确保每次请求的安全性。结合两者,可以构建出既安全又高效的认证体系。
25 1
|
16天前
|
数据采集 机器学习/深度学习 存储
使用 Python 清洗日志数据
使用 Python 清洗日志数据
20 2
|
2月前
|
缓存 NoSQL Linux
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
110 1
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
|
1月前
|
SQL 人工智能 运维
在阿里云日志服务轻松落地您的AI模型服务——让您的数据更容易产生洞见和实现价值
您有大量的数据,数据的存储和管理消耗您大量的成本,您知道这些数据隐藏着巨大的价值,但是您总觉得还没有把数据的价值变现出来,对吗?来吧,我们用一系列的案例帮您轻松落地AI模型服务,实现数据价值的变现......
165 3
|
2月前
|
数据库 Java 监控
Struts 2 日志管理化身神秘魔法师,洞察应用运行乾坤,演绎奇幻篇章!
【8月更文挑战第31天】在软件开发中,了解应用运行状况至关重要。日志管理作为 Struts 2 应用的关键组件,记录着每个动作和决策,如同监控摄像头,帮助我们迅速定位问题、分析性能和使用情况,为优化提供依据。Struts 2 支持多种日志框架(如 Log4j、Logback),便于配置日志级别、格式和输出位置。通过在 Action 类中添加日志记录,我们能在开发过程中获取详细信息,及时发现并解决问题。合理配置日志不仅有助于调试,还能分析用户行为,提升应用性能和稳定性。
44 0
|
2月前
|
开发者 前端开发 编解码
Vaadin解锁移动适配新境界:一招制胜,让你的应用征服所有屏幕!
【8月更文挑战第31天】在移动互联网时代,跨平台应用开发备受青睐。作为一款基于Java的Web应用框架,Vaadin凭借其组件化设计和强大的服务器端渲染能力,助力开发者轻松构建多设备适应的Web应用。本文探讨Vaadin与移动设备的适配策略,包括响应式布局、CSS媒体查询、TouchKit插件及服务器端优化,帮助开发者打造美观且实用的移动端体验。通过这些工具和策略的应用,可有效应对屏幕尺寸、分辨率及操作系统的多样性挑战,满足广大移动用户的使用需求。
45 0
|
2月前
|
存储 运维 监控
Entity Framework Core 实现审计日志记录超棒!多种方法助你跟踪数据变化、监控操作,超实用!
【8月更文挑战第31天】在软件开发中,审计日志记录对于跟踪数据变化、监控用户操作及故障排查至关重要。Entity Framework Core (EF Core) 作为强大的对象关系映射框架,提供了多种实现审计日志记录的方法。例如,可以使用 EF Core 的拦截器在数据库操作前后执行自定义逻辑,记录操作类型、时间和执行用户等信息。此外,也可通过在实体类中添加审计属性(如 `CreatedBy`、`CreatedDate` 等),并在保存实体时更新这些属性来记录审计信息。这两种方法都能有效帮助我们追踪数据变更并满足合规性和安全性需求。
39 0
|
2月前
|
SQL 安全 测试技术
【数据守护者必备】SQL数据备份与恢复策略全解析:从全量到日志备份,手把手教你确保企业信息万无一失的实战技巧!
【8月更文挑战第31天】数据库是企业核心业务数据的基石,为防止硬件故障、软件错误或人为失误导致的数据丢失,制定可靠的备份与恢复策略至关重要。本文通过一个在线购物平台的案例,详细介绍了使用 SQL Server 进行全量备份、差异备份及事务日志备份的方法,并演示了如何利用 SQL Server Agent 实现自动化备份任务。此外,还提供了数据恢复的具体步骤和测试建议,确保数据安全与业务连续性。
82 0
日志服务数据加工最佳实践: 多子键为数组的复杂JSON加工
程序构建的日志经常会以一种统计性质的JSON格式写入, 通常其包含一个基础信息, 以及多个子健为数组的形式. 本篇如何使用日志服务数据加工处理多子键为数组的复杂JSON.
1098 0
|
12天前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
87 3