使用私钥生成JSON Web令牌(JWT)

时间:2019-10-05 14:19:28

标签: java openssl jwt

我正在尝试生成JWT,但收到此错误:

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout private.key -out certificate_pub.crt

我正在使用io.jsonwebtoken.Jwts库和字符串形式的私钥,但出现错误。

Map<String, Object> payload = new HashMap<>();
payload.put("iss", orgId);
payload.put("sub", accountId);
payload.put("exp", expirationTime);
payload.put("aud", new 
StringBuilder("Url").append("/c/").append(apiKey).toString());
payload.put(new StringBuilder("Url").append("/s/entt_sdk").toString(), Boolean.TRUE);
return Jwts.builder().setClaims(payload).**signWith**(SignatureAlgorithm.RS256, privateKeyStr).compact();
java.lang.IllegalArgumentException: Base64-encoded key bytes may only be specified for HMAC signatures.  If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.

我的私钥如下:

-----BEGIN PRIVATE KEY-----
sajdkjsadkjsahdkjsadksadkjsadkjs
-----END PRIVATE KEY-----

1 个答案:

答案 0 :(得分:2)

错误非常简单-此方法只能用于Hmac算法。对于基于RSA的算法,您将必须使用signWith(SignatureAlgorithm, Key)

我将使用的密钥将不是PEM格式-它将是base64 DER编码的字符串-为此,我必须摆脱该密钥的PEM格式的开头和结尾------BEGIN PRIVATE KEY----------END PRIVATE KEY-----

MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9/xBGBRhpSBa/
Xc/5CeAQjjVMcXfIFOqeIc/kq7dnsLz+ntTrvTE3fyz0E8J8MLMTNypK7irt8MB0
0Gpm/NJHnLSGqgSqIXAvUbUsxCO8ULSTKLTQs4RiDbUtOWZgacvRN0IYRnN2tDWf
DWTYAElBSValTt/jvHw72BMcLXd8plGQYYD52l6+w/7ENgLG+hNbVewdM/saJKyL
Y/jhRl758XWGw5bCmIYk9BCbUVDLc5PN+iiYoBFTQYwP0Y1ln58vNZ/CDBw2mW3q
TyploxoAdmG86km4EK2mtlhWBaUshfHORxGkWlCXcwazWDoc5QJ24McaYbcQOcPW
lLDgP8MvAgMBAAECggEAHDX6MZtiE4fbsNB6J+06ctrauR4D/hZ0+8PjfX2tvty0
Q05MKTCvVSEyCI/CifQlMs43HmccwrXDrdSgZ+hURMPU3kXyaVyLrssADsSU1cpZ
9ZvOtUpidri4VR23wMsUs1z0GGylilOZvqMbfSMVvXbpQaRjhAohnDUqKT3rBvvd
fqO8KFl8FCgMEbbPvym5tJvrYfe9WalisnrGrrCZoaBmR5dEbjUfWrMg6bMcfPlz
rVaney8+UdFu15RUXTno3mu+glIYz1MyYk6LdlgBrb19gBscykqi0wYhZ312Yk0B
SXx+RIi49oZy7IU4jybzOSqWL79L4rQdvtBrp/dx6QKBgQDn/XeuCATwLdFyeo4/
ksVlhXIp9ykAZSFk/wnapcsvLSV59edI8mkslAwTTbgqPn0hvxVdwf0k23wipkGl
FiujHMCGoeT9ZwYs9uDEkGABATXomr7eC64AEfuUnUZMj3s0BgG5S/mGonlkIlTt
RpvxzMeYnRvLjDXZMP7FKCz0DQKBgQDRqPq+w7MQFBaBMTE7+685QeR+xxGnMipW
Qf579E++ihslGx6LztQnFhbah2VEVCPBq7R/BiEHiW4bA+DiTC8HnMsZi3jhlO9q
yw0DSZUSX8vsgNW2ghJOF9JnZEbptN3RlD11koSvkFZiUuxHYa0n6ti38CwfLxgV
MCuL5XOZKwKBgGi4CqD9L7V3CTdiyPk7eG1mOm1lCxYJkHR1h24yLrCB8YvHC3rr
Kbycq4K/L2WqRXPJPIzQ90L+7F77q2AozNPZM7LSO3qDWc9MNZOlFCD/+eSgjY3P
ueCAPY8NG2GN1vBZ0cdh2yYCC0e/E5TzrYsNg/+I07Yi+V+r9STsCLa1AoGAJnJo
WOcmRQKKBfLxZmCHB2bv8dergw+N9/duJWjt3rEQvUM13Ml22hwQ4M4HYfpT/EXy
eYC0Od+X01houtbhoPG9xNdwuV1Icjr+DeZGcfIjQSF3D1rW5H811EPtRRonuzEF
/DN8JX3AeZNfRM/CoxlL2J8wWB+YuPn2YlcXVbUCgYEAmVETM7+OBW9YKtv6zvKe
OZeZUIDIUZDqZgLd3IT7rikVCedIljWNhroXU1wNMssJPkfiQToGaykUMbBcgZKI
neU2IuYWaLXBN9oAj1u7/YQ0DpPqk/Sb2FpVX5eKfp4cu8XdyezxNuFFsPVdGBhB
xhqJOJuUc/ZKbo5Stc3NXEE=

这里是如何读取此密钥并对其进行签名的示例:

//create payload
Map<String, Object> payload = new HashMap<>();
payload.put("iss", "orgId");
payload.put("sub", "orgId");
payload.put("exp", "orgId");
payload.put("aud", new
StringBuilder("Url").append("/c/").append("key").toString());
payload.put(new StringBuilder("Url").append("/s/entt_sdk").toString(), Boolean.TRUE);

// read key
String privateKeyB64 = Files.lines(Paths.get("src/main/resources/private.key")).collect(Collectors.joining());
byte[] privateKeyDecoded = Base64.getDecoder()
                .decode(privateKeyB64);

//create key spec
PKCS8EncodedKeySpec spec =
                new PKCS8EncodedKeySpec(privateKeyDecoded);

// create key form spec
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(spec);

//create signed JWT - JWS
String jws = Jwts.builder().setClaims(payload).signWith(SignatureAlgorithm.RS256, privateKey).compact();

System.out.println(jws);

注意,我使用PKCS8EncodedKeySpec是因为您的密钥似乎是PKCS8格式。输出为:

eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJvcmdJZCIsImF1ZCI6IlVybC9jL2tleSIsImlzcyI6Im9yZ0lkIiwiZXhwIjoib3JnSWQiLCJVcmwvcy9lbnR0X3NkayI6dHJ1ZX0.m8ASk4kUNx41csikpd0zALLQTjwG2pc0Ba0D9PGLVbI2NaY0IIXgaVVVJcIERz4ejj_jfq436v6v0_QnxdmvjMAnx88UmHGdrCT0V5MZl008LP4g4LrV-WczNltCUpoJQ-4CW6xkpXD03JIDQAYwaKb-PIOtm-pfLJhPPmxykc8QioueijhI5M__Pq5Nq0JCbkQxfGzxE5m_gJwwq7n290RBGRYH6AHeClaEJhDzLNitIejNvvua4zNNC6S1CHsa4ChaEFfRb9bi-jNEQW27IGhrKRCtuwleFwigl7oTIsyaRWlzuVNYcZHS707Z2o6Mkf9hDo8AGKURUVsJgA8WIg

我在Java 8上对其进行了测试。对于Java 11,我收到了一个有关XML处理的缺少模块的错误。