我有以下RSA私钥,我必须生成一个JWT 令牌使用 RS256算法。
以下是我的示例私钥:
-----BEGIN RSA PRIVATE KEY----- /
MIIEoAIBAAKCAQEAnFWdIwBbLRw4xfFDXYFmlXKB4BpKeuAtfh1dcs5mhod0WTo/
i/Z4DOpiiw/2H05luI4PzOZem8AlHI9hUhHq5p1+YHM68SyvBQ9OTl+O90nmLYOt
2Jzquks11bf29nJh7KwGVHOv2nh3eL39BVsqHSt0O/rjSa0bV+QtUc2DP9U4WzZ3
8RhT2bdiRcsDuMfI024u9JGG/O4iG3wDlXyS5j6G0NVw/KEJJtYYv8ruQVpvlKUd
Ntx7aE+u6F60SjJYQSfdjMoQNMDglBFwhY11RlHSmiJ/Ym8aE+Hj11JHhPcB1N+X
RWaHV9ply4TnE13PsQtGWVKsLDNQNUeIUljKdQIDAQABAoIBAAa4d3owYxBcDOTA
K7vdUDekezN9wy3nwozlXkW33G3JbOsDt1pLoiWL/eh/Kyl1XqdsaVQkTco28bbP
Qx5wFBUN4tzqlzdpoFcrV/EZPTV268+RFZbLnXDyGBez7N3zVNpZGtHj7JoLtmHD
vm4jLnr1NJik1G3aZI6GtJwLpaocwtKWHB59hVwF5NinW6BXN0ALNfwKwU4vMWYo
I65F2zvGMVl9rbfvU+E73DXK3TN5tLOAkqZMQ8+g/VnNd/XuZwh2ZADokEXV8aNR
7zVm3MCCcaa8IKJMrgnb9q47tzfyaoIu5aRYGYKZ/8wuItv4Dal30MK1CQoCD8cD
5uzorQECgYEA9+QTCXrVHzhJJm+QWQZrXu7ydk+tEix7WY9ZY702OHiTO2x9IT4d
4lKFbLhQrQMAFhO3B31Hq5ODGS4jB3bFzATrtOR9eLCR7l+0Az2FcU1Zmqsdkyv8
zlkD9oOYif6rICrVyLQ/lbQF7erVDRbxJUjeKqGAnvELrlzcr+rx+XECgYEAoXLQ
MdR+OLsP5XbcoA//Z2pgwwKZVs282MfYjZLVqeEAAC8BB9+8HHrtMaJGvADI06OV
7lTCDaE8UlqgzN2B55FmCTiLABjhk3fEDrhGVe4jhEZz1i8t0ArjsYTwXs/uXoUz
YP2rcJtkybOQEzjbvM4s5+B8iht+dYaqwoW5/0UCgYAp68UYZlBiXjdoq5dCpuZD
gK86ONEw8JrPk4Fvb5EazbFAbGFg3Mta+c+cijMCfy5ljWH3f0U+i8yw1m+QFJLw
pKhjx/w8C8gyArdDkQTfG1Ca6nMu71JqZv1Xk/uY4pt37iaHMYxLOc2C5aKv+wA+
6OrBVNyWhHcQPp4Hlfjj0QJ/de5oJf4SNV5vPi6U+la1OdV62PgNCls+lxtkFAYu
DOlOFtQ+7IGB50vj912STcJE8FOOMYm4NjyQ05df3kXvnjeXUST8ZBXIsO/LRvVU
a3CIgRb1hn7v+Af8Sq/Q5XD9rg2eejrSAG+CL9P6ahAecswoATj5v+hVd4PnODB2
rQKBgAwe3pkQRFHjameLHip+xcHQ85aASiLjhTvFhFjRHDpJ+FoiJ2H4xi4/jd1F
KGrhMpVnLXKwe1HaONFPV3yEFK2da1r66iIr/opcx1hyKmV1xvebcUxYYoRY6j/g
JMsceBR10oGEath+43rS78LASIQG83PmTYhkcEkQNftxEGqC
-----END RSA PRIVATE KEY-----
标题
{
"alg": "RS256",
"typ": "JWT"
}
正文:
{
"iss": "14a2fecb-ddd7-4823-46e2-67515bc01734",
"sub": "13f7982d-1f78-46e2-4823-3273568fce89",
"iat": 1521132568,
"exp": 1522136156,
"aud": "account-d.example.com",
"scope": "signature"
}
以下是我的示例Java代码:
package com.knyc.demo;
import java.security.spec.PKCS8EncodedKeySpec;
import org.bouncycastle.util.encoders.Base64;
import org.mule.api.MuleEventContext;
import org.mule.api.lifecycle.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.jsonwebtoken.*;
import java.util.Date;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
public class GenerateJwtToken implements Callable{
protected final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public String onCall(MuleEventContext eventContext) throws Exception {
String issuer = "14a2fecb-ddd7-4823-a9cc-67515bc01734";
String scope = "signature";
String subject = "13f7982d-1f78-46e2-a843-3273568fce89";
String audience = "account-d.docusign.com";
String privateKeyPEM ="-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIEoAIBAAKCAQEAnFWdIwBbLRw4xfFDXYFmlXKB4BpKeuAtfh1dcs5mhod0WTo/\n" +
"i/Z4DOpiiw/2H05luI4PzOZem8AlHI9hUhHq5p1+YHM68SyvBQ9OTl+O90nmLYOt\n" +
"2Jzquks11bf29nJh7KwGVHOv2nh3eL39BVsqHSt0O/rjSa0bV+QtUc2DP9U4WzZ3\n" +
"8RhT2bdiRcsDuMfI024u9JGG/O4iG3wDlXyS5j6G0NVw/KEJJtYYv8ruQVpvlKUd\n" +
"Ntx7aE+u6F60SjJYQSfdjMoQNMDglBFwhY11RlHSmiJ/Ym8aE+Hj11JHhPcB1N+X\n" +
"RWaHV9ply4TnE13PsQtGWVKsLDNQNUeIUljKdQIDAQABAoIBAAa4d3owYxBcDOTA\n" +
"K7vdUDekezN9wy3nwozlXkW33G3JbOsDt1pLoiWL/eh/Kyl1XqdsaVQkTco28bbP\n" +
"Qx5wFBUN4tzqlzdpoFcrV/EZPTV268+RFZbLnXDyGBez7N3zVNpZGtHj7JoLtmHD\n" +
"vm4jLnr1NJik1G3aZI6GtJwLpaocwtKWHB59hVwF5NinW6BXN0ALNfwKwU4vMWYo\n" +
"I65F2zvGMVl9rbfvU+E73DXK3TN5tLOAkqZMQ8+g/VnNd/XuZwh2ZADokEXV8aNR\n" +
"7zVm3MCCcaa8IKJMrgnb9q47tzfyaoIu5aRYGYKZ/8wuItv4Dal30MK1CQoCD8cD\n" +
"5uzorQECgYEA9+QTCXrVHzhJJm+QWQZrXu7ydk+tEix7WY9ZY702OHiTO2x9IT4d\n" +
"4lKFbLhQrQMAFhO3B31Hq5ODGS4jB3bFzATrtOR9eLCR7l+0Az2FcU1Zmqsdkyv8\n" +
"zlkD9oOYif6rICrVyLQ/lbQF7erVDRbxJUjeKqGAnvELrlzcr+rx+XECgYEAoXLQ\n" +
"MdR+OLsP5XbcoA//Z2pgwwKZVs282MfYjZLVqeEAAC8BB9+8HHrtMaJGvADI06OV\n" +
"7lTCDaE8UlqgzN2B55FmCTiLABjhk3fEDrhGVe4jhEZz1i8t0ArjsYTwXs/uXoUz\n" +
"YP2rcJtkybOQEzjbvM4s5+B8iht+dYaqwoW5/0UCgYAp68UYZlBiXjdoq5dCpuZD\n" +
"gK86ONEw8JrPk4Fvb5EazbFAbGFg3Mta+c+cijMCfy5ljWH3f0U+i8yw1m+QFJLw\n" +
"pKhjx/w8C8gyArdDkQTfG1Ca6nMu71JqZv1Xk/uY4pt37iaHMYxLOc2C5aKv+wA+\n" +
"6OrBVNyWhHcQPp4Hlfjj0QJ/de5oJf4SNV5vPi6U+la1OdV62PgNCls+lxtkFAYu\n" +
"DOlOFtQ+7IGB50vj912STcJE8FOOMYm4NjyQ05df3kXvnjeXUST8ZBXIsO/LRvVU\n" +
"a3CIgRb1hn7v+Af8Sq/Q5XD9rg2eejrSAG+CL9P6ahAecswoATj5v+hVd4PnODB2\n" +
"rQKBgAwe3pkQRFHjameLHip+xcHQ85aASiLjhTvFhFjRHDpJ+FoiJ2H4xi4/jd1F\n" +
"KGrhMpVnLXKwe1HaONFPV3yEFK2da1r66iIr/opcx1hyKmV1xvebcUxYYoRY6j/g\n" +
"JMsceBR10oGEath+43rS78LASIQG83PmTYhkcEkQNftxEGqC\n" +
"-----END RSA PRIVATE KEY-----";
String privKeyPEM = privateKeyPEM.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");
/* byte [] encoded = Base64.decode(privKeyPEM);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
*/
try {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256;
long nowMs = System.currentTimeMillis()/1000;
long expMs = nowMs + 3600;
Date now = new Date(nowMs);
Date exp = new Date(expMs);
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(privKeyPEM);
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
System.out.println(signingKey);
JwtBuilder builder = Jwts.builder()
.setIssuedAt(now)
.setSubject(subject)
.setIssuer(issuer)
.setAudience(audience)
.claim("scope",scope)
.signWith(signatureAlgorithm, signingKey)
.setExpiration(exp);
return builder.compact();
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}
抛出异常说: "必须使用RSA PrivateKey计算RSA签名。 javax.crypto.spec.SecretKeySpec类型的指定键不是RSA PrivateKey。"
提前致谢...
答案 0 :(得分:1)
您可以使用此库https://github.com/jwtk/jjwt
package <your package name>;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
public class JWT {
private String privateKey;
<your other props such as issuer etc.>
public JWT(String privateKey) {
this.privateKey = privateKey;
}
public String encode() {
String retStr = null;
Claims claims = Jwts.claims();
claims.put("issuer", "14a2fecb-ddd7-4823-a9cc-67515bc01734");
claims.put("scope", "signature");
claims.put("subject", "13f7982d-1f78-46e2-a843-3273568fce89");
claims.put("audience", "account-d.docusign.com");
// strip the headers
privateKey = privateKey.replace("-----BEGIN RSA PRIVATE KEY-----", "");
privateKey = privateKey.replace("-----END RSA PRIVATE KEY-----", "");
privateKey = privateKey.replaceAll("\\s+","");
byte[] encodedKey = android.util.Base64.decode(this.privateKey, android.util.Base64.DEFAULT);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
try {
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(keySpec);
retStr = Jwts.builder().setClaims(claims).signWith(privKey).compact();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return retStr;
}
}
答案 1 :(得分:0)
如果你们中的一些人仍在努力生成 jwt 令牌,特别是对于 Docusign Auth 服务,也许这个例子也适用于你:
在开始之前,请在 linux 机器上使用此命令以正确格式转换您的 RSA 私钥: 将您的密钥复制并粘贴到文件中并启动:
openssl pkcs8 -topk8 -nocrypt -in privatekeyOLD -out privatekeyNEW
再次复制生成的新密钥后,将代码粘贴到变量 String rsaPrivateKey 中(也许您会删除在复制和粘贴过程中生成的一些额外字符) 作为参考,我使用了这个 https://www.viralpatel.net/java-create-validate-jwt-token/
所需的 JDK 11
import io.jsonwebtoken.Jwts;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;
public class JWTIO{
// reference https://www.viralpatel.net/java-create-validate-jwt-token/
public static String createJwtSignedHMAC() throws InvalidKeySpecException, NoSuchAlgorithmException {
PrivateKey privateKey = getPrivateKey();
Instant now = Instant.now();
String jwtToken = Jwts.builder()
.setIssuer("2a03dbc6-XXXX-XXXXX-XXXX-7e9ac9df613f")
.setSubject("2a285ff3-XXXX-XXXX-XXXXX-e433497afc23")
.setAudience("account-d.docusign.com")
.claim("scope","signature impersonation")
.setIssuedAt(Date.from(now))
.setExpiration(Date.from(now.plus(5l, ChronoUnit.MINUTES)))
.signWith(privateKey)
.compact();
return jwtToken;
}
private static PrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
/* before to put the rsa private key in your String you must convert in PKCSS#8
* THE CERTIFICATE PROVIDED BY DOCUSIGN IS PKCS#1 and does not works
* copy the rsa provate key ina file and use this command in linux ubuntu for
* example
* openssl pkcs8 -topk8 -nocrypt -in privatekeyOLD -out privatekeyNEW
* */
String rsaPrivateKey = "-----BEGIN PRIVATE KEY-----" +
"MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCKAIc+hqdKgcPb" +
"9XbR5Osbdeq1J14zxRG58CkrHZO0PMSf/smoCEyEcxhGsjrITl/sLv/q8iOVMKgY" +
"KdpOMIoPDGCF8KCXA4F9hM/WXJstprEeqPi7a1FnXzi3uwaf+jy2zUviDt09jm+g" +
"uu5TaZzTuzyoClEgfwIu2LwuHaJKtjceRKHWKvUqqxBQMXlq/s5lNXWajWSpLffP" +
"/5L0YfCK9uW1FJJXT4cP9fiNbcd6GiHGwVk/eJy4QYaR9lWNvnKKu1H52xgWkLC+" +
"TwfOtcqtjF9sWE5XIAjpdFVh5u64g/uOafKzEF/yVOTzPvYUWI3PhKjqSS3V3yhk" +
"TqoFG53hAgMBAAECggEALo0NEgdkCRsK0XjUsurQb/vvx1nXSglQ+HLNwFCC0Yqq" +
"HPpaVccu4ILejoJyl7zwWIBmLX+uhxXZrgT4MeXnvDnFmYjY8vfox0l0vm+QnO6c" +
"0qXW+Ymy9PbG8BszmeVUc6l+zmuLL8eLWiGUYSjAESAYzupkAV02hEzx9XBjnWWl" +
"ifoWOXvO22ADtO8jRk1ODbOrqyt1Hz7UDLtQI6Vdw3QovadW/3hKCx+0a/WxgDhR" +
"VosPudbzIGYBzdnbOyT+ToVIyMBTJU/8muZbWsaaOXHhel9lD/CUjvCcivL5tcSU" +
"0KvEiHVCXWfojbuy/RksgSTvl/aFEOrmqRjyu2JEbQKBgQDt+B4r6NVuqOPus+Xb" +
"RHF8QpvtwzIWSxxAwbtAWxWDJSrMMlhAx1yZ4kefSxbxAkdNkv9vQoVabVAEiWdJ" +
"VzXB8W9tvcD57zrbiraHQI5hCn+t5GIsSTnbhg6CG2dxv58uWviDneeNEdDeki+b" +
"vwTTXuHIeyCnPdLI/vaMzO0clwKBgQCUdVm5IYxRd93ohYH14zIfty+7J301iB3t" +
"t/fccrg1qjx4WniLbhLweVYdL44XpzMZUzdAYFhyHUIyAWIR4yHC3b0+u34oshjv" +
"MD/gjWPiNTBBthYTy559todm3jyj+g9Z+gLLu2G93+wGl3u15igiTy0oMmh4bS3s" +
"xtFk1pLQRwKBgF8L+wEOvjC0xFVTBTvO2oUHFcChdh/xYBd9SY0q1CzNa4qjkRxO" +
"hG3yMykslL0ua8xQKjYGG71Ca/Nj7h0c+Bu+kwMCB1HMe3W0sbLT1gpsZxLNZWjK" +
"1pEXujO9PlPwdWPOcfQf3Zw6wXIkcV+DrCnAe+3XP/OMfeRJ8a/LKemBAoGAf46M" +
"9wqiO+WYH4+G6LS7fpCxTEdTx8kangQxzZIsQL/ykR568KI1V7WJji4sEpqwxxO/" +
"J2sg03vcQob5spDLk1lenyYN8f2Eew+j8tbJebVlrzA6q+uKVE2e7X4J8IKM6ixs" +
"doycIL7jV46U1ufYmBIbpKwbI0375bO2esP7BUUCgYBqmx7GJnyOapOYlR7wHhYL" +
"rXk0QWwE7j3d4zQCHGOqzFqWxyIi1hsQYCwgOeobmd0r5kULRRptYBKvflEiboVq" +
"RL3VeyR9ZIEDkbCUewwf2qn6EoOCfi7x6/36brhn8r3mWC9rvNiKB33iBJrkin1p" +
"f0aUgyrlhk1aMnDDBFFb8A==" +
"-----END PRIVATE KEY-----";
rsaPrivateKey = rsaPrivateKey.replace("-----BEGIN PRIVATE KEY-----", "");
rsaPrivateKey = rsaPrivateKey.replace("-----END PRIVATE KEY-----", "");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(rsaPrivateKey));
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(keySpec);
return privKey;
}
}
所需的库
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
要调用这个方法,你必须用 try catch 包围它,然后你就可以开始了 示例:
String bearer = null;
try {
bearer = JWTIO.createJwtSignedHMAC();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
答案 2 :(得分:0)
由于行分隔符,它不起作用。您还应该删除 \n by
PT_DYNAMIC
之后
privKeyPEM = privKeyPEM.replaceAll("\n", "");