密码改造相关配置项与对外/对内接口约定。
一期(互联网管理端短信双因子 +ruoyi-crypto骨架)后端已落地,本文档与代码保持一致。
# 密码改造总开关(一期:crypto 模块 Stub 已接入,二期起用于字段加解密)
crypto:
enabled: true
hsm:
provider: stub # 开发联调 stub;生产改为 vendor-sdk 对接密码机
hosts:
- 127.0.0.1:8008
connect-timeout-ms: 5000
read-timeout-ms: 10000
pool-size: 20
keys:
credential:
hmac-index: 10
sm4-index: 1
personal:
hmac-index: 11
sm4-index: 2
permission:
hmac-index: 12
log:
hmac-index: 13
business:
hmac-index: 14
sm4-index: 3
# 登录鉴别
# auth-mode: ruoyi → 若依默认登录(账号+密码+图形验证码),不要求 smsCode
# auth-mode: sms-2fa → 互联网双因子(还须 sys_login_policy 命中 SMS_2FA)
login:
auth-mode: sms-2fa
network-zone: INTERNET # INTERNAL / INTERNET
internet-sms:
enabled: true # auth-mode 未配置时的等价开关;false = 若依默认登录
code-length: 6
code-ttl-seconds: 300
send-interval-seconds: 60
# 短信网关(登录双因子)
sms:
provider: aliyun
aliyun:
enabled: true
dry-run: true # true=开发态仅写日志;生产配齐密钥后设 false
access-key-id: ${ALIYUN_SMS_ACCESS_KEY_ID:}
access-key-secret: ${ALIYUN_SMS_ACCESS_KEY_SECRET:}
sign-name: ${ALIYUN_SMS_SIGN_NAME:}
template-code: ${ALIYUN_SMS_TEMPLATE_CODE:} # 模板变量须含 code
region: cn-hangzhou
request-timeout-seconds: 10
任选其一即可恢复改造前登录方式(无需 smsCode):
| 方式 | 配置 | 说明 |
|---|---|---|
| 推荐 | login.auth-mode: ruoyi |
语义清晰,优先于下方开关 |
| 等价 | login.internet-sms.enabled: false |
与 auth-mode: ruoyi 效果相同 |
修改后重启应用生效。/login/sms/send 在关闭双因子时将返回「短信双因子登录未启用」。
| 配置项 | 说明 |
|---|---|
crypto.enabled |
密码改造总开关;false 时业务可跳过加解密(仅建议迁移双写期) |
crypto.hsm.provider |
stub=BouncyCastle 开发实现;生产对接密码机 SDK |
crypto.keys.* |
各数据类型在密码机内的密钥索引(非密钥本身) |
login.auth-mode |
ruoyi / sms-2fa;非空时优先于 internet-sms.enabled |
login.network-zone |
与 sys_login_policy.network_zone 配合解析策略 |
login.internet-sms.* |
OTP 长度、Redis TTL、同 IP 发送间隔 |
sms.aliyun.dry-run |
true 或未配齐 AccessKey 时仅打日志 Stub,不调阿里云 API |
sms.aliyun.* |
阿里云 dysmsapi SendSms 参数 |
crypto:
integrity:
verify-on-read: true
verify-before-update: true
patrol-cron: "0 0 2 * * ?"
patrol-batch-size: 500
alert:
sms-enabled: false
notify-roles: admin,security
sign-server:
enabled: true
base-url: https://10.0.0.20:8443/sign-api
app-id: baqing-admin
connect-timeout-ms: 5000
login:
cert:
enabled: true
challenge-ttl-seconds: 300
| 方法 | 路径 | 说明 | 状态 |
|---|---|---|---|
| POST | /login/sms/send |
发送登录短信验证码 | ✅ 已实施 |
| POST | /login |
原接口增加可选字段 smsCode |
✅ 已实施 |
前置条件:login.auth-mode=sms-2fa(或 internet-sms.enabled=true),且 sys_login_policy / 用户 login_policy 解析为 SMS_2FA。
POST /login/sms/send
{
"username": "admin",
"uuid": "图形验证码uuid",
"code": "图形验证码"
}
POST /login(互联网双因子)
{
"username": "admin",
"password": "******",
"code": "图形验证码",
"uuid": "图形验证码uuid",
"smsCode": "123456"
}
POST /login(若依默认,auth-mode=ruoyi)
{
"username": "admin",
"password": "******",
"code": "图形验证码",
"uuid": "图形验证码uuid"
}
短信相关错误提示(i18n)
| 场景 | 用户提示 |
|---|---|
| 缺少 smsCode | 请输入短信验证码 |
| 验证码错误 | 短信验证码错误 |
| 验证码过期 | 短信验证码已失效 |
| 发送过频 | 短信发送过于频繁,请稍后再试 |
| 未绑定手机 | 账号未绑定手机号,无法登录 |
| 方法 | 路径 | 说明 | 状态 |
|---|---|---|---|
| GET | /login/cert/challenge |
获取登录随机数 challenge | ⏳ 待实施 |
| POST | /login/cert |
证书验签登录 | ⏳ 待实施 |
POST /login/cert 请求体(规划)
{
"certBase64": "MIIC...",
"signedData": "MEUCI...",
"challenge": "a1b2c3d4-e5f6-..."
}
| 模块 | 包/类 | 说明 |
|---|---|---|
ruoyi-crypto |
com.ruoyi.crypto.service.CryptoService |
SM3/SM4 统一接口 |
ruoyi-crypto |
StubCryptoServiceImpl |
开发态密码机 Stub |
ruoyi-framework |
LoginSmsService |
短信双因子发送/校验 |
ruoyi-framework |
LoginProperties |
login.* 配置 |
ruoyi-framework |
AliyunSmsGatewayClient |
阿里云 dysmsapi 封装 |
ruoyi-framework |
SmsProperties |
sms.* 配置 |
ruoyi-system |
SysLoginPolicyServiceImpl |
登录策略解析 |
baqing-admin |
SysLoginController |
/login、/login/sms/send |
public interface CryptoService {
String hmacSm3(byte[] plain, CryptoDataType dataType);
String encryptSm4(String plainText, CryptoDataType dataType);
String decryptSm4(String cipherText, CryptoDataType dataType);
boolean verifyHmac(byte[] plain, String storedHmac, CryptoDataType dataType);
}
| 项 | 值 |
|---|---|
| Maven 坐标 | com.aliyun:alibabacloud-dysmsapi20170525:4.0.10 |
| 实现类 | AliyunSmsGatewayClient |
| 调用 API | AsyncClient.sendSms |
| 模板参数 | {"code":"123456"} |
开发联调:sms.aliyun.dry-run=true 时,验证码写入应用日志(关键字 【短信Stub】),无需真实发短信。
生产启用:配置 AccessKey、签名、模板,设 dry-run=false。
| Key | 说明 |
|---|---|
login:sms:{mobile} |
OTP 明文,TTL 默认 300s,校验成功后删除 |
login:sms:limit:{ip} |
同 IP 发送间隔,默认 60s |
public interface IntegrityService {
String computeAndStore(String tableName, Object entity);
void verifyOnRead(String tableName, Object entity);
void patrolTable(String tableName, int batchSize);
}
| 异常 | HTTP | 用户提示 |
|---|---|---|
SmsCodeRequiredException |
200 + 业务错误 | 请输入短信验证码 |
SmsCodeException |
200 + 业务错误 | 短信验证码错误 |
SmsCodeExpireException |
200 + 业务错误 | 短信验证码已失效 |
CryptoIntegrityException |
409 | 数据完整性校验失败(二期) |
CryptoException |
500 | 系统安全服务暂不可用 |
CertVerifyException |
401 | 证书验签失败(待实施) |
| 脚本 | 说明 | 状态 |
|---|---|---|
sql/crypto_phase1.sql |
一期:sys_user 扩展、sys_login_policy |
✅ 已提供 |
sql/crypto_migration.sql |
二~三期全量 DDL | ⏳ 待编写 |
ruoyi-crypto Stub SM3/SM4 单元测试POST /login/sms/send + POST /login 后端接口login.auth-mode 切换若依默认登录sql/crypto_phase1.sqlsmsCode(见前端方案,可选)auth-mode=sms-2fa + dry-run=false| 项 | 值 |
|---|---|
| 密码机厂商 | (待填) |
| 密码机型号 | (待填) |
| SDK 版本 | (待填) |
| 验签服务器厂商 | (待填) |
| 验签接口文档版本 | (待填) |
| 短信网关 | 阿里云 dysmsapi |
| 短信 SDK | alibabacloud-dysmsapi20170525 4.0.10 |