PRAJIN PRAKASH
PRAJIN PRAKASH

Reputation: 1475

Docusign JWT authentication returns no valid keys or signatures error in Java but works fine with JavaScript why?

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

Answers (1)

PRAJIN PRAKASH
PRAJIN PRAKASH

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

Related Questions