JWS in Nimbus VS Signature

Issue #302 resolved
Yury Morozov created an issue

Hi team!

I have a problem with communication between server protected by JWS token by Nimbus-JOSE-JWT and .Net. I was trying to investigate the reason and found that if I sign with Signature sig = Signature.getInstance("SHA256withRSA"); on Java side, I have exactly the same signature I have in .Net. When I'm using jwsObject, I got another result.

Could you please check what is the reason or how can I generate same values in .Net?

import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.util.Base64URL;
import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;


public class Main {

    public static void main(String[] args) throws NoSuchAlgorithmException {
        String pk = "308204bf020100300d06092a864886f70d0101010500048204a9308204a50201000282010100b29012e2f56cb55b7e5fccccc0b446fac3356a9d8b9ca848934be41de5b24ddf47ad387521b6e8e5ade6484a04aa33463bc397ec6d14857e3c9df8007d78d77a00e977c65cd64157661fe094872513cc93d021f355d193858da66cc83093f762e560903958e82d1585bc67fee4ee0ce11619415cb7f389358bf1f6845dd36bba099fb3b57f08957abfdf877da417f62a668c8fa3f3e5e883f4a8a44acb6e14c382baf58d04b6dfd078c820b49cff614c091bfbf4766258b78fe62a9388e605157f2c75e923ad0cb2d05c14f1c0677c3ee0148201f34baf8dfc64edc393125579600883057d9d91d9005c1281bf9537234f9cef5a523996b79411d1bbb44caf110203010001028201001900f5b4143bd1b56b1fcd14cad333b13f8e864c63555f77323109536a6baa5ddeb291da4d0b48d7889f5b7609eb2f5ce15785399518af8cbabe40110980d7637d27341f71b68ad5cb3621838add1545ab5914b7f7476e89e008f2e8a16cc6d2715e3133e6903467f41f2accd58fc3fbecd54282d23b66f6398f7b3e93c8dc27a7b29292fc9b1520f55a766ee70adee5c2045e963441879c694f9586ebfbb7fc932121659fdc280b1754f6dc470a5ef8b37135e7e818eb6ff03ab1a5b712fc0c27b070e0dc33b019f73bfb76c1621a3416e98e3a286843bb3ae845108b467a824081e7310f94e509c94dc97999f8e4d2fb4037ef7eaeb52ae497ce0e02bf8a8502818100eb8f6407c614de76d3ca31512c7fba5bd869f8d4e98ffe7cb1e2f09ad822cffbadece33ba68053c41e0858da9a8dce396db72951ae21a226a124f680d39a736608d405c6d9553b9cf4fc0daf3f24ababbbcb34989db064dd2b8fc7558b6f590c4d28bc71ab02a07268b3e9a4a61ea290cef25d00aa65c26200f1c5a9bacf5b0f02818100c20e92f9c2efd11fea898e7c3543c4489a122b64d144a67e8485da56392096c21c00daec6f0a55ba69fa8d437c868d44b24558ba53837b18a092ad3697095e6fd6d930779f1a68d92c94d0d07fbb0eaa603046a4099425850785bb425d0670d0a22bb04a27f7bc2f35abb5645a960d72c86fca3bca3080e8b437d3002071d3df0281810080077b72ce3261876c2d2508dd8abe9b54d0a431f49012dd6b41d14c17d533fdb2d661daf5f02197224b9f1f918929610544dbec4d1c72a9544466c6363c6824390023f3a404335667c0e71f2cce9d8fc58df8944a80a9119caf94c3e5f92b090896ef754861311b7dd4eb545605a88dd42cde679235a4a4e7a680ac73a067f9028181008e1681c362da99b2d6d6158018b81fd6510990c06701ef2e9ff62a220bfe32a4ba405e0bd45a2adf2d8e09352ace924d8482862f17cb23acaa95fb42076112c6acf7a6275055d40380430e8a3b9c4966b2bb665de1ad99b34808c14e1c3305139e4a82f029479980afb9a43d709e820653809701245053730fd1f82b159682dd02818100dac81e64366b90d959d05d3f0c3f977e8ec0418f5d995595f07bcadc48eb10fde1cb2d65fc4dc92fa719b918120a664f0ae3a718f7af47aef0f3035760aaf9f3aa47a6def5939ca96e9f70d6dfaaab5b3dfb0f9325b49e9803ae2aebe12d99bee1975d76bf9418dfdd32b5e2bbdcc71ac131a12a107ba2ebc1846f90c6f53a52";
        String payload="eyJ4NXQjUzI1NiI6ImRyWDZfTVg1VENoV29EUjRBbDZtN3pzdUcxQno5Mkp0RW1wUHVBSDE2RWciLCJhbGciOiJSUzI1NiJ9.L3YyL2FwaS9jYXJkcy9vcmRlcnsiZXh0ZXJuYWxJZCI6Ijk5ODg3NjI4LTcxMDcwNTciLCJwcml2YXRlQ2xpZW50Ijp7Im5hbWUiOiJKb2huIiwic3VybmFtZSI6IkRvZSIsIm1vYmlsZVBob25lIjoiMzcxMTIzNDU2NzgiLCJlbWFpbCI6ImpvaG4uZG9lQG1haWwuY29tIiwibGFuZ3VhZ2UiOiJlbiIsInVuaXFJZCI6IkFCQzEyMyIsImRvY3VtZW50Ijp7InR5cGUiOiJEUklWSU5HX0xJQ0VOU0UiLCJudW1iZXIiOiJVT0xPNDY4N0dTOVVFMjciLCJjb3VudHJ5Q29kZSI6IkdCUiIsImlzc3VpbmdEYXRlIjoiMjAxNC0wMS0yOSIsImV4cGlyeURhdGUiOiIyMDI0LTAxLTI4IiwiYmlydGhEYXRlIjoiMTk5NC0xMC0yNiJ9LCJwZXAiOiJOTyIsImNvbW1lbnQiOiJVbmtub3duIHBlcnNvbiIsImN1cnJlbnRBZGRyZXNzIjp7ImNvdW50cnkiOiJMVkEiLCJjaXR5IjoiUmlnYSIsInN0cmVldCI6IkR1bnRlcyA2IiwiemlwQ29kZSI6IkxWMzgwNyJ9LCJwcmV2aW91c0FkZHJlc3MiOnsiY291bnRyeSI6IkxWQSIsImNpdHkiOiJSaWdhIiwic3RyZWV0IjoiRHVudGVzIDYiLCJ6aXBDb2RlIjoiTFYzODA3In0sInllYXJJbmNvbWUiOnsiY2N5IjoiRVVSIiwidmFsdWUiOiIxMDAwMC4zNCJ9fSwiY2FyZCI6eyJwcm9kdWN0Q29kZSI6IjEwMCIsImNhcmRBY2NvdW50IjoiNzc3IiwiY3VycmVuY2llcyI6WyJFVVIiXSwiaG9sZGVyIjp7Im5hbWUiOiJKb2huIiwic3VybmFtZSI6IkRvZSIsIm1vYmlsZVBob25lIjoiMzcxMjM0NTYyMyIsImVtYWlsIjoiam9obi5kb2VAbWFpbC5jb20iLCJsYW5ndWFnZSI6ImVuIiwicm9sZSI6Ik9XTkVSIn0sImRlbGl2ZXJ5QWRkcmVzcyI6eyJjb3VudHJ5IjoiTFZBIiwiY2l0eSI6IlJpZ2EiLCJzdHJlZXQiOiJEdW50ZXMgNiIsInppcENvZGUiOiJMVi0zODA3Iiwic2hpcG1lbnQiOiJTVEFOREFSRCIsIm5hbWUiOiJKb2huIiwic3VybmFtZSI6IkRvZSIsInBob25lIjoiKzM3MTIzNDU1In0sInN1cHBsZW1lbnRhcnkiOmZhbHNlLCJhY2NvdW50T3duZXJSZWxhdGlvbiI6Ik9XTkVSIn19";


        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(DatatypeConverter.parseHexBinary(pk));
        KeyFactory kf = null;
        try {
            kf = KeyFactory.getInstance("RSA");
            RSAPrivateKey key = (RSAPrivateKey) kf.generatePrivate(keySpec);

            JWSObject jwsObject = new JWSObject(
                    new JWSHeader.Builder(JWSAlgorithm.RS256).x509CertSHA256Thumbprint(new Base64URL("drX6_MX5TChWoDR4Al6m7zsuG1Bz92JtEmpPuAH16Eg")).build(),
                    new Payload("/v1/api/cards/order{\"externalId\":\"99887628-7107057\",\"privateClient\":{\"name\":\"John\",\"surname\":\"Doe\",\"mobilePhone\":\"37112345678\",\"email\":\"john.doe@mail.com\",\"language\":\"en\",\"uniqId\":\"ABC123\",\"document\":{\"type\":\"DRIVING_LICENSE\",\"number\":\"UOLO4687GS9UE27\",\"countryCode\":\"GBR\",\"issuingDate\":\"2014-01-29\",\"expiryDate\":\"2024-01-28\",\"birthDate\":\"1994-10-26\"},\"pep\":\"NO\",\"comment\":\"Unknown person\",\"currentAddress\":{\"country\":\"LVA\",\"city\":\"Riga\",\"street\":\"Duntes 6\",\"zipCode\":\"LV3807\"},\"previousAddress\":{\"country\":\"LVA\",\"city\":\"Riga\",\"street\":\"Duntes 6\",\"zipCode\":\"LV3807\"},\"yearIncome\":{\"ccy\":\"EUR\",\"value\":\"10000.34\"}},\"card\":{\"productCode\":\"100\",\"cardAccount\":\"777\",\"currencies\":[\"EUR\"],\"holder\":{\"name\":\"John\",\"surname\":\"Doe\",\"mobilePhone\":\"3712345623\",\"email\":\"john.doe@mail.com\",\"language\":\"en\",\"role\":\"OWNER\"},\"deliveryAddress\":{\"country\":\"LVA\",\"city\":\"Riga\",\"street\":\"Duntes 6\",\"zipCode\":\"LV-3807\",\"shipment\":\"STANDARD\",\"name\":\"John\",\"surname\":\"Doe\",\"phone\":\"+37123455\"},\"supplementary\":false,\"accountOwnerRelation\":\"OWNER\"}}")
            );

            JWSSigner signer = new RSASSASigner(key);
            jwsObject.sign(signer);
            String jws = jwsObject.serialize();

            Base64URL signature = RSASign(payload.getBytes(StandardCharsets.UTF_8), key);

            System.out.println(jws);
            System.out.println(signature);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (JOSEException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Base64URL RSASign(byte[] DataToSign, RSAPrivateKey key) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, JOSEException {

        Signature sig = Signature.getInstance("SHA256withRSA");
        sig.initSign(key);

        sig.update(DataToSign);
        return Base64URL.encode(sig.sign());
    }
}

Comments (2)

  1. Log in to comment