
# 如何生成JWT Token？
数据建模引擎（xDM Foundation，简称xDM-F）的应用运行态支持使用JSON Web Token（JWT）进行认证。用户可在本地环境中通过提供的Shell脚本，快速生成符合"Java PKCS#8"规范的RSA密钥对，并利用示例脚本签发采用RS256算法的JWT Token。生成的密钥与Token可直接用于运行态接口调用。
#### 环境准备
在执行脚本前，请确保系统环境满足以下要求：
| 组件        | 最低版本     | 检查命令                       | 说明                         |
|:---|:---|:---|:---|
| OpenSSL   | 1.1.1及以上 | ``` openssl version ```    | 核心加密工具，负责密钥生成与数字签名。        |
| Bash      | 4.0及以上   | ``` echo $BASH_VERSION ``` | 脚本运行环境，支持Linux、macOS、WSL2。 |
| Coreutils | -        | ``` tr --version ```       | 包含printf、tr、grep等基础文本处理工具。 |
   
![](https://support.huaweicloud.com/sdkreference-idme/public_sys-resources/caution_3.0-zh-cn.png)
Windows系统不支持原生CMD/PowerShell，所有操作需在Git Bash或WSL2环境中执行。
#### 创建脚本文件
在工作目录下创建两个可执行脚本，分别实现"RSA密钥对生成"和"JWT Token签发"功能。
- **脚本1：RSA密钥对生成脚本（gen_keys.sh** ）
  新建文件，命名为"gen_keys.sh"，并将以下完整代码复制到文件中：
  ```
  #!/bin/bash
  # Description: 生成RSA 3072位密钥对，并同步保存纯Base64文本文件
  # 1. 生成PKCS#8格式私钥 (JJWT默认推荐格式)
  openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:3072
  # 2. 从私钥中提取公钥
  openssl rsa -pubout -in private.pem -out public.pem
  # 3. 提取纯Base64字符串并存入文件
  grep -v -- "-----" private.pem | tr -d '[:space:]' > private_base64.txt
  grep -v -- "-----" public.pem | tr -d '[:space:]' > public_base64.txt
  # 4. 设置私钥文件权限（仅当前用户可读写）
  chmod 600 private.pem private_base64.txt
  echo "==========================================================="
  echo "密钥生成成功！"
  echo "1. 标准PEM文件 (用于OpenSSL/Nginx): private.pem, public.pem"
  echo "2. 纯Base64文件 (用于Java配置): private_base64.txt, public_base64.txt"
  echo "==========================================================="
  ```
  

- **脚本2：JWT Token签发脚本（gen_token.sh** ）
  新建文件，命名为"gen_token.sh"，并将以下完整代码复制到文件中：
  ```
  #!/bin/bash
  # Description: 使用本地私钥PEM文件签发JWT Token (RS256)
  PRI_KEY_FILE="private.pem"
  if [ ! -f "$PRI_KEY_FILE" ]; then
      echo "错误: 未找到私钥文件$PRI_KEY_FILE，请先运行gen_keys.sh"
      exit 1
  fi
  # 1. 构造Header (Base64Url编码)
  header_json='{"alg":"RS256","typ":"JWT"}'
  header=$(printf '%s' "$header_json" | openssl base64 -e -A | tr -d '=' | tr '/+' '_-')
  # 2. 构造Payload (Base64Url编码)
  iat=$(date +%s)
  exp=$((iat + 86400)) # 24小时后过期
  payload_json="{\"sub\":\"admin_user\",\"iat\":$iat,\"exp\":$exp,\"role\":\"developer\"}"
  payload=$(printf '%s' "$payload_json" | openssl base64 -e -A | tr -d '=' | tr '/+' '_-')
  # 3. 计算签名 (Signature)
  unsigned_token="$header.$payload"
  signature=$(printf '%s' "$unsigned_token" | \
              openssl dgst -sha256 -sign "$PRI_KEY_FILE" | \
              openssl base64 -e -A | tr -d '=' | tr '/+' '_-')
  # 4. 组合最终Token
  final_token="$header.$payload.$signature"
  echo "==========================================================="
  echo "已签发JWT Token:"
  echo "$final_token"
  echo "==========================================================="
  ```
  
 
#### 执行脚本
1. 打开终端，进入脚本所在目录，执行如下命令，赋予脚本执行权限。 
   ```
   chmod +x gen_keys.sh gen_token.sh
   ```
   
   
2. 执行如下命令，生成RSA密钥对。 
   ```
   ./gen_keys.sh
   ```
   执行成功后，目录下会生成4个文件：
   - private.pem：标准PEM私钥，仅用于本地签发Token，严禁泄漏。
   
   - public.pem：标准PEM公钥，用于常规签名验证。
   
   - private_base64.txt：纯Base64私钥，用于特定Java配置文件。
   
   - public_base64.txt：纯Base64公钥，需配置到xDM-F运行态中。
   
   
   
   
3. 打开"public_base64.txt"文件，复制其全部内容，并将其填入xDM-F运行态配置文件（YAML格式）的对应位置。 
   ```
   containers:
     - env:
         - name: jwt.standby.ks
           value: >-
             {"public":"此处粘贴“public_base64.txt”的完整内容"}
   ```
   ![](https://support.huaweicloud.com/sdkreference-idme/public_sys-resources/caution_3.0-zh-cn.png)
   请确保JSON格式正确，不要遗漏双引号或大括号。
   
   
4. 执行如下命令，获取Token。 
   ```
   ./gen_token.sh
   ```
   执行完成后，终端将直接输出可用的JWT Token字符串。
   
   
 
#### 使用方法
在发起API请求时，将生成的Token放入HTTP请求头中：
```
x-jwt-token: <Token>
```
#### 安全与注意事项
- "private.pem"和"private_base64.txt"文件为核心密钥文件，**严禁提交至Git仓库、分享给他人或在非安全环境中传输！**
- 脚本默认使用RS256算法，若Java后端要求其他算法（如PS512），需同步修改"gen_token.sh"脚本中的两处位置：
  - Header中的"alg"字段。
  
  - "openssl dgst"命令中的哈希参数（如修改为"-sha512"）。
   
- 根据业务安全策略，**定期重新生成并更换密钥对**，提升系统安全性。
 
