基于 ECDSA(椭圆曲线数字签名算法)生成 JWT Token

1. 为什么选择 ECDSA(椭圆曲线数字签名算法)

JWT Token 提供的签名算法有对称和非对称两种。通常在业务网关或微服务间的零信任场景下的 Token 验证,验证 Token 签名的密钥管理是主要问题。如果有其他方案能够提升对称加密密钥安全与验证签名性能,则可不考虑使用非对成加密算法进行签名。使用 ECDSA 有以下优势:

  • 非对称加密算法相较于对称加密算法密钥管理安全度更高;
  • ECDSA 相较于 RSA 相同的安全级别使用的密钥更短,相反使用较长的密钥 ECDSA 的安全度更高;
  • ECDSA 相较于 RSA 所需计算资源更少;

2. 生成签名公私钥

2.1. 使用 Open SSL 生成公私钥

openssl ecparam -genkey -name secp521r1 -out ./crt/access-token-ec-private-key.pem
openssl ec -in ./crt/access-token-ec-private-key.pem -pubout -out ./crt/access-token-ec-public-key.pem

2.2. Java 语言 pkcs8 格式私钥转换

openssl pkcs8 -topk8 -inform pem -in ./crt/access-token-ec-private-key.pem -outform pem -nocrypt -out ./crt/access-token-ec-private-key-pkcs8.pem

3. SpringBoot 分环境配置密钥

3.1. yaml 文件配置

token:
  access:
    publicKey: '粘贴公钥'
    privateKey: '粘贴私钥'

3.2. 密钥配置类

@Configuration
public class JWTSecretConfigure {

    private static final String ALGORITHM = "EC";

    @Value("${token.access.privateKey}")
    private String accessTokenECPrivateKey;

    @Value("${token.access.publicKey}")
    private String accessTokenECPublicKey;

    @Bean("AccessTokenECPrivateKey")
    public ECPrivateKey createAccessTokenECPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {

        KeyFactory kf = KeyFactory.getInstance(ALGORITHM);
        EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(accessTokenECPrivateKey));
        return (ECPrivateKey) kf.generatePrivate(keySpec);
    }

    @Bean("AccessTokenECPublicKey")
    public ECPublicKey createAccessTokenECPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException {

        KeyFactory kf = KeyFactory.getInstance(ALGORITHM);
        EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(accessTokenECPublicKey));
        return (ECPublicKey) kf.generatePublic(keySpec);
    }
}

4. 使用 auth0 生成 JWT Token

4.1. 依赖

<properties>
        <auth0-jwt.version>3.6.0</auth0-jwt.version>
</properties>   
<dependencies>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>${auth0-jwt.version}</version>
        </dependency>
</dependencies>

4.2. 生成 Token

// 注入密钥
@Resource(name = "AccessTokenECPrivateKey")
private ECPrivateKey accessTokenECPrivateKey;

@Resource(name = "AccessTokenECPublicKey")
private ECPublicKey accessTokenECPublicKey;

// 生成 Token
Algorithm algorithm = Algorithm.ECDSA512(accessTokenECPublicKey, accessTokenECPrivateKey);
String accessToken = JWT.create()
                .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRES))
                .withIssuedAt(new Date())
                .withIssuer(ISSUER)
                .sign(algorithm);

5. 注意事项

  • 在要求性能场景下需要做好基准测试,评估使用 ECDSA 签名算法签发 Token 的性能是否符合要求。
  • 非对称加密算法相对于对称加密算法管理密钥安全性有提升,但请注意私钥仅在签发 Token 的服务中使用,且定期更换。
  • 基于配置文件的密钥管理请确保配置文件网络传输加密且配置有白名单或其他访问配置文件的认证方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值