Reputation: 1475
To work with docusign JWT Sign (documentation) ,The JWS creation works fine with java script with this library with the following code. but its not working with Java implementation using io.jsonwebtoken
var currTime = Math.round(Date.now()/1000);
var expTime = currTime+3600;
var header = {
"alg": "RS256"
};
var data = {
"iat": currTime,
"exp" : expTime,
"iss": "xxxx",
"sub": "xxxx",
"aud": "account-d.docusign.com",
"scope": "impersonation signature"
};
var secret = "-----BEGIN RSA PRIVATE KEY-----XXXXX-----END RSA PRIVATE KEY-----";
var sHeader = JSON.stringify(header);
var sPayload = JSON.stringify(data);
var jws = KJUR.jws.JWS.sign("RS256", sHeader, sPayload, secret);
The Java implementation
final String ISS = "xxxx";
final String SUB = "xxxx";
final String AUD = "account-d.docusign.com";
final String SCOPE = "impersonation signature";
final String SECRET =
"-----BEGIN RSA PRIVATE KEY-----\r\nXXXXX\r\n-----END RSA PRIVATE KEY-----";
Long currTime = System.currentTimeMillis();
Long expTime = currTime+3600;
Map<String,Object> header = new HashMap<>();
Map<String,Object> data = new HashMap<>();
header.put("alg","RS256");
data.put("iat",currTime);
data.put("exp",expTime);
data.put("iss",ISS);
data.put("sub",SUB);
data.put("aud",AUD);
data.put("scope",SCOPE);
java.security.Security.addProvider(
new org.bouncycastle.jce.provider.BouncyCastleProvider()
);
KeyFactory kf = KeyFactory.getInstance("RSA"); // or "EC" or whatever
PemObject pem = new PemReader(new StringReader(SECRET)).readPemObject();
byte[] der = pem.getContent();
PrivateKey privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(der));
String jws = Jwts.builder()
.setHeader(header)
.setClaims(data)
.signWith(privateKey, SignatureAlgorithm.RS256)
.compact();
which returns the following 400 error.
{
"error": "invalid_grant",
"error_description": "no_valid_keys_or_signatures"
}
Upvotes: 1
Views: 1583
Reputation: 1475
Sorry its my mistake the timestamp makes the error System.currentTimeMillis()/1000
fixed the issue
final String ISS = "xxxx";
final String SUB = "xxxx";
final String AUD = "account-d.docusign.com";
final String SCOPE = "impersonation signature";
final String SECRET =
"-----BEGIN RSA PRIVATE KEY-----\r\nXXXXX\r\n-----END RSA PRIVATE KEY-----";
Long currTime = System.currentTimeMillis()/1000;
Long expTime = currTime+3600;
Map<String,Object> header = new HashMap<>();
Map<String,Object> data = new HashMap<>();
header.put("alg","RS256");
data.put("iat",currTime);
data.put("exp",expTime);
data.put("iss",ISS);
data.put("sub",SUB);
data.put("aud",AUD);
data.put("scope",SCOPE);
java.security.Security.addProvider(
new org.bouncycastle.jce.provider.BouncyCastleProvider()
);
KeyFactory kf = KeyFactory.getInstance("RSA"); // or "EC" or whatever
PemObject pem = new PemReader(new StringReader(SECRET)).readPemObject();
byte[] der = pem.getContent();
PrivateKey privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(der));
String jws = Jwts.builder()
.setHeader(header)
.setClaims(data)
.signWith(privateKey, SignatureAlgorithm.RS256)
.compact();
Upvotes: 1