RsaJsonWebKeyTest.java
/*
* Copyright 2012-2017 Brian Campbell
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jose4j.jwk;
import org.jose4j.keys.ExampleRsaKeyFromJws;
import org.jose4j.lang.JoseException;
import org.junit.Test;
import java.security.interfaces.RSAPrivateCrtKey;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.jose4j.jwk.JsonWebKey.OutputControlLevel.*;
import static org.junit.Assert.*;
/**
*/
public class RsaJsonWebKeyTest
{
// key from http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-13#appendix-A.3.1
// it was shown as octets in -11 and before
private static final String RSA_JWK_WITH_PRIVATE_KEY =
"{\"kty\":\"RSA\",\n" +
" \"n\":\"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddx\n" +
" HmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMs\n" +
" D1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSH\n" +
" SXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdV\n" +
" MTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8\n" +
" NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ\",\n" +
" \"e\":\"AQAB\",\n" +
" \"d\":\"Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97I\n" +
" jlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0\n" +
" BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn\n" +
" 439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYT\n" +
" CBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLh\n" +
" BOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ\"\n" +
"}";
@Test
public void testParseExampleWithPrivate() throws JoseException
{
JsonWebKey jwk = JsonWebKey.Factory.newJwk(RSA_JWK_WITH_PRIVATE_KEY);
PublicJsonWebKey pubJwk = (PublicJsonWebKey) jwk;
assertEquals(ExampleRsaKeyFromJws.PRIVATE_KEY, pubJwk.getPrivateKey());
assertEquals(ExampleRsaKeyFromJws.PUBLIC_KEY, pubJwk.getPublicKey());
}
@Test
public void testFromKeyWithPrivate() throws JoseException
{
PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk(ExampleRsaKeyFromJws.PUBLIC_KEY);
String jsonNoPrivateKey = jwk.toJson();
jwk.setPrivateKey(ExampleRsaKeyFromJws.PRIVATE_KEY);
String dKey = "\"" + RsaJsonWebKey.PRIVATE_EXPONENT_MEMBER_NAME + "\"";
assertFalse(jwk.toJson().contains(dKey));
assertEquals(jsonNoPrivateKey, jwk.toJson());
assertTrue(jwk.toJson(INCLUDE_PRIVATE).contains(dKey));
}
@Test
public void testFromKeyWithCrtPrivateAndBackAndAgain() throws JoseException
{
String json = "{\"kty\":\"RSA\",\n" +
" \"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4\n" +
" cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMst\n" +
" n64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2Q\n" +
" vzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbIS\n" +
" D08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw\n" +
" 0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\",\n" +
" \"e\":\"AQAB\",\n" +
" \"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9\n" +
" M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqij\n" +
" wp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d\n" +
" _cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBz\n" +
" nbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFz\n" +
" me1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q\",\n" +
" \"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPV\n" +
" nwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqV\n" +
" WlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\n" +
" \"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyum\n" +
" qjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgx\n" +
" kIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk\",\n" +
" \"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oim\n" +
" YwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_Nmtu\n" +
" YZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\n" +
" \"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUU\n" +
" vMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9\n" +
" GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk\",\n" +
" \"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzg\n" +
" UIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rx\n" +
" yR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\n" +
" \"alg\":\"RS256\",\n" +
" \"kid\":\"2011-04-29\"}";
doKeyWithCrtPrivateAndBackAndAgain(json);
}
@Test
public void testFromCrtAndBackWithJwsAppendixA2() throws JoseException
{
String json =
" {\"kty\":\"RSA\",\n" +
" \"n\":\"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddx\n" +
" HmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMs\n" +
" D1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSH\n" +
" SXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdV\n" +
" MTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8\n" +
" NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ\",\n" +
" \"e\":\"AQAB\",\n" +
" \"d\":\"Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97I\n" +
" jlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0\n" +
" BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn\n" +
" 439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYT\n" +
" CBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLh\n" +
" BOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ\",\n" +
" \"p\":\"4BzEEOtIpmVdVEZNCqS7baC4crd0pqnRH_5IB3jw3bcxGn6QLvnEtfdUdi\n" +
" YrqBdss1l58BQ3KhooKeQTa9AB0Hw_Py5PJdTJNPY8cQn7ouZ2KKDcmnPG\n" +
" BY5t7yLc1QlQ5xHdwW1VhvKn-nXqhJTBgIPgtldC-KDV5z-y2XDwGUc\",\n" +
" \"q\":\"uQPEfgmVtjL0Uyyx88GZFF1fOunH3-7cepKmtH4pxhtCoHqpWmT8YAmZxa\n" +
" ewHgHAjLYsp1ZSe7zFYHj7C6ul7TjeLQeZD_YwD66t62wDmpe_HlB-TnBA\n" +
" -njbglfIsRLtXlnDzQkv5dTltRJ11BKBBypeeF6689rjcJIDEz9RWdc\",\n" +
" \"dp\":\"BwKfV3Akq5_MFZDFZCnW-wzl-CCo83WoZvnLQwCTeDv8uzluRSnm71I3Q\n" +
" CLdhrqE2e9YkxvuxdBfpT_PI7Yz-FOKnu1R6HsJeDCjn12Sk3vmAktV2zb\n" +
" 34MCdy7cpdTh_YVr7tss2u6vneTwrA86rZtu5Mbr1C1XsmvkxHQAdYo0\",\n" +
" \"dq\":\"h_96-mK1R_7glhsum81dZxjTnYynPbZpHziZjeeHcXYsXaaMwkOlODsWa\n" +
" 7I9xXDoRwbKgB719rrmI2oKr6N3Do9U0ajaHF-NKJnwgjMd2w9cjz3_-ky\n" +
" NlxAr2v4IKhGNpmM5iIgOS1VZnOZ68m6_pbLBSp3nssTdlqvd0tIiTHU\",\n" +
" \"qi\":\"IYd7DHOhrWvxkwPQsRM2tOgrjbcrfvtQJipd-DlcxyVuuM9sQLdgjVk2o\n" +
" y26F0EmpScGLq2MowX7fhd_QJQ3ydy5cY7YIBi87w93IKLEdfnbJtoOPLU\n" +
" W0ITrJReOgo1cq9SbsxYawBgfp_gh6A5603k2-ZQwVK0JKSHuLFkuQ3U\"\n" +
" }";
doKeyWithCrtPrivateAndBackAndAgain(json);
}
private void doKeyWithCrtPrivateAndBackAndAgain(String json) throws JoseException
{
PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk(json);
assertTrue(jwk.getPrivateKey() instanceof RSAPrivateCrtKey);
String jsonOut = jwk.toJson(PUBLIC_ONLY);
assertFalse(jsonOut.contains("\"d\""));
assertFalse(jsonOut.contains("\"p\""));
assertFalse(jsonOut.contains("\"q\""));
assertFalse(jsonOut.contains("\"dp\""));
assertFalse(jsonOut.contains("\"dq\""));
assertFalse(jsonOut.contains("\"qi\""));
jsonOut = jwk.toJson();
assertFalse(jsonOut.contains("\"d\""));
assertFalse(jsonOut.contains("\"p\""));
assertFalse(jsonOut.contains("\"q\""));
assertFalse(jsonOut.contains("\"dp\""));
assertFalse(jsonOut.contains("\"dq\""));
assertFalse(jsonOut.contains("\"qi\""));
jsonOut = jwk.toJson(INCLUDE_SYMMETRIC);
assertFalse(jsonOut.contains("\"d\""));
assertFalse(jsonOut.contains("\"p\""));
assertFalse(jsonOut.contains("\"q\""));
assertFalse(jsonOut.contains("\"dp\""));
assertFalse(jsonOut.contains("\"dq\""));
assertFalse(jsonOut.contains("\"qi\""));
jsonOut = jwk.toJson(INCLUDE_PRIVATE);
assertTrue(jsonOut.contains("\"d\""));
assertTrue(jsonOut.contains("\"p\""));
assertTrue(jsonOut.contains("\"q\""));
assertTrue(jsonOut.contains("\"dp\""));
assertTrue(jsonOut.contains("\"dq\""));
assertTrue(jsonOut.contains("\"qi\""));
JsonWebKeyTest.checkEncoding(jsonOut, RsaJsonWebKey.MODULUS_MEMBER_NAME ,RsaJsonWebKey.EXPONENT_MEMBER_NAME,
RsaJsonWebKey.PRIVATE_EXPONENT_MEMBER_NAME, RsaJsonWebKey.FIRST_PRIME_FACTOR_MEMBER_NAME, RsaJsonWebKey.SECOND_PRIME_FACTOR_MEMBER_NAME,
RsaJsonWebKey.FIRST_FACTOR_CRT_EXPONENT_MEMBER_NAME, RsaJsonWebKey.SECOND_FACTOR_CRT_EXPONENT_MEMBER_NAME, RsaJsonWebKey.FIRST_CRT_COEFFICIENT_MEMBER_NAME);
PublicJsonWebKey jwkAgain = PublicJsonWebKey.Factory.newPublicJwk(jsonOut);
assertTrue(jwkAgain.getPrivateKey() instanceof RSAPrivateCrtKey);
assertEquals(jwk.getPrivateKey(), jwkAgain.getPrivateKey());
}
@Test
public void testToJsonWithPublicKeyOnlyJWKAndIncludePrivateSettings() throws JoseException
{
PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk(ExampleRsaKeyFromJws.PUBLIC_KEY);
String jsonNoPrivateKey = jwk.toJson(PUBLIC_ONLY);
PublicJsonWebKey publicOnlyJWK = PublicJsonWebKey.Factory.newPublicJwk(jsonNoPrivateKey);
assertThat(jsonNoPrivateKey,is(equalTo(publicOnlyJWK.toJson(INCLUDE_PRIVATE))));
}
}