只能为 HMAC 签名指定 Base64 编码的密钥字节
Posted
技术标签:
【中文标题】只能为 HMAC 签名指定 Base64 编码的密钥字节【英文标题】:Base64-encoded key bytes may only be specified for HMAC signatures 【发布时间】:2018-10-16 11:51:57 【问题描述】:您好,我正在使用 Spring Security 在 Spring Boot 中编写 JWT。当我在正文部分使用以下详细信息向邮递员请求 POST 时
"userName": "RAM",
"id":123,
"role": "admin"
然后我得到以下错误
"timestamp": "2018-05-06T14:57:12.048+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Base64-encoded key bytes may only be specified for HMAC signatures. If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.",
"path": "/token"
我在下面的代码中使用了生成器的 jwt builder
@Component
public class JwtGenerator
public String generate(JwtUser jwtUser)
// TODO Auto-generated method stub
Claims claim= Jwts.claims()
.setSubject(jwtUser.getUserName());
claim.put("userId", String.valueOf(jwtUser.getId()));
claim.put("role", jwtUser.getRole());
String secret = "YouTube";
byte[] bytesEncoded = Base64.getEncoder().encode(secret.getBytes());
return Jwts.builder().setClaims(claim).signWith(SignatureAlgorithm.ES512, secret).compact();
//With(SignatureAlgorithm.ES512, bytesEncoded).compact();
//signWith(SignatureAlgorithm.ES512,"YouTube").compact();
我使用直接字符串值作为密钥和其他两种可能的组合,但无法找出问题所在。我还从下面的代码中提供了 JwtBuilder 中 DefaultJwtBuilder 所期望的编码字符串,仍然没有命中。
@Override
public JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey)
Assert.hasText(base64EncodedSecretKey, "base64-encoded secret key cannot be null or empty.");
Assert.isTrue(alg.isHmac(), "Base64-encoded key bytes may only be specified for HMAC signatures. If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.");
byte[] bytes = TextCodec.BASE64.decode(base64EncodedSecretKey);
return signWith(alg, bytes);
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:你从“SignatureAlgorithm.ES512, secret”切换到“SignatureAlgorithm.HS512, secret”,只需要用户名&&密码
【讨论】:
【参考方案2】:您代码中的签名算法是使用椭圆曲线算法的 ES512。由于您使用的是密钥,因此您希望使用前缀为“HS”的 HMAC 算法。所以 HS256、HS384 或 HS512。
更改Jwts.builder().setClaims(claim).signWith(SignatureAlgorithm.ES512, secret).compact();
致Jwts.builder().setClaims(claim).signWith(SignatureAlgorithm.HS512, secret).compact();
【讨论】:
为我工作!这应该被标记为正确答案! 很高兴记住使用密钥真的很长;)以上是关于只能为 HMAC 签名指定 Base64 编码的密钥字节的主要内容,如果未能解决你的问题,请参考以下文章
网络安全——Base64编码MD5SHA1-SHA512HMAC(SHA1-SHA512)哈希
如何在matlab中使用base64输出重现相同的python hmac
Hmac在Google Apps脚本中登录,当Secret和Digest是base64编码时
python3与python2编码导致 hmac.new/base64.b64encode('value') python3各种报错