/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.cxf.rs.security.jose.jwk;
import java.math.BigInteger;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import org.apache.cxf.rs.security.jose.common.JoseException;
import org.apache.cxf.rs.security.jose.common.JoseUtils;
import org.apache.cxf.rs.security.jose.common.KeyManagementUtils;
import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
import org.apache.cxf.rt.security.crypto.CryptoUtils;
import org.junit.Assert;
import org.junit.Test;
public class JwkUtilsTest extends Assert {
private static final String RSA_KEY = "{"
+ "\"kty\": \"RSA\","
+ "\"n\": \"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAt"
+ "VT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn6"
+ "4tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FD"
+ "W2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n9"
+ "1CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINH"
+ "aQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\","
+ "\"e\": \"AQAB\","
+ "\"alg\": \"RS256\","
+ "\"kid\": \"2011-04-29\""
+ "}";
private static final String EC_256_KEY = "{"
+ "\"kty\": \"EC\","
+ "\"x\": \"CEuRLUISufhcjrj-32N0Bvl3KPMiHH9iSw4ohN9jxrA\","
+ "\"y\": \"EldWz_iXSK3l_S7n4w_t3baxos7o9yqX0IjzG959vHc\","
+ "\"crv\": \"P-256\""
+ "}";
private static final String EC_384_KEY = "{"
+ "\"kty\": \"EC\","
+ "\"x\": \"2jCG5DmKUql9YPn7F2C-0ljWEbj8O8-vn5Ih1k7Wzb-y3NpBLiG1BiRa392b1kcQ\","
+ "\"y\": \"7Ragi9rT-5tSzaMbJlH_EIJl6rNFfj4V4RyFM5U2z4j1hesX5JXa8dWOsE-5wPIl\","
+ "\"crv\": \"P-384\""
+ "}";
private static final String EC_521_KEY = "{"
+ "\"kty\": \"EC\","
+ "\"x\": \"Aeq3uMrb3iCQEt0PzSeZMmrmYhsKP5DM1oMP6LQzTFQY9-F3Ab45xiK4AJxltXEI-87g3gRwId88hTyHgq180JDt\","
+ "\"y\": \"ARA0lIlrZMEzaXyXE4hjEkc50y_JON3qL7HSae9VuWpOv_2kit8p3pyJBiRb468_U5ztLT7FvDvtimyS42trhDTu\","
+ "\"crv\": \"P-521\""
+ "}";
private static final String OCTET_KEY_1 = "{"
+ "\"kty\": \"oct\","
+ "\"k\": \"ZW8Eg8TiwoT2YamLJfC2leYpLgLmUAh_PcMHqRzBnMg\""
+ "}";
private static final String OCTET_KEY_2 = "{"
+ "\"kty\": \"oct\","
+ "\"k\": \"NGbwp1rC4n85A1SaNxoHow\""
+ "}";
@Test
public void testRsaKeyModulus() throws Exception {
JsonWebKey jwk = JwkUtils.readJwkKey(RSA_KEY);
String modulus = jwk.getStringProperty(JsonWebKey.RSA_MODULUS);
assertEquals(256, JoseUtils.decode(modulus).length);
RSAPublicKey pk = JwkUtils.toRSAPublicKey(jwk);
JsonWebKey jwk2 = JwkUtils.fromRSAPublicKey(pk, jwk.getAlgorithm());
String modulus2 = jwk2.getStringProperty(JsonWebKey.RSA_MODULUS);
assertEquals(256, JoseUtils.decode(modulus2).length);
assertEquals(modulus2, modulus);
}
@Test
public void testFromToPrivateRsaKey() throws Exception {
RSAPrivateKey privateKey1 =
(RSAPrivateKey)KeyManagementUtils.loadPrivateKey("org/apache/cxf/rs/security/jose/jws/alice.jks",
"password",
"alice",
"password",
null);
JsonWebKey jwk1 = JwkUtils.fromRSAPrivateKey(privateKey1, KeyAlgorithm.RSA_OAEP_256.getJwaName());
assertNotNull(jwk1.getProperty(JsonWebKey.RSA_PUBLIC_EXP));
assertNotNull(jwk1.getProperty(JsonWebKey.RSA_PRIVATE_EXP));
RSAPrivateKey privateKey2 = JwkUtils.toRSAPrivateKey(jwk1);
assertEquals(privateKey2, privateKey1);
}
@Test
public void testFromToPublicRsaKey() throws Exception {
RSAPublicKey publicKey1 =
(RSAPublicKey)KeyManagementUtils.loadPublicKey("org/apache/cxf/rs/security/jose/jws/alice.jks",
"password",
"alice",
null);
JsonWebKey jwk1 = JwkUtils.fromRSAPublicKey(publicKey1, KeyAlgorithm.RSA_OAEP_256.getJwaName());
assertNotNull(jwk1.getProperty(JsonWebKey.RSA_PUBLIC_EXP));
assertNull(jwk1.getProperty(JsonWebKey.RSA_PRIVATE_EXP));
RSAPublicKey publicKey2 = JwkUtils.toRSAPublicKey(jwk1);
assertEquals(publicKey2, publicKey1);
}
@Test
public void testFromToPublicRsaKey2() throws Exception {
BigInteger n = new BigInteger(
"525569531153621228164069013206963023039121751335221395180741421479892725873020691336158448746650762107595"
+ "8352148531548486906896903886764928450353366890712125983926472500064566992690642117517954169974907061547"
+ "3353190040609042090075291281955112293781438730376121249764205272939686534594208819023639183157456093565"
+ "4148815673814517535941780340023556224072529306118783149589148262622268860151306096159642808944513667279"
+ "4704664637866917427597486905443676772669967766269923280637049233876979061993814679654208850149406432368"
+ "2161337544093644200063709176660451323844399667162451308704624790051211834667782115390754507376506824717"
+ "9938484919159962066058375588059543574624283546151162925649987580839763809787286157381728046746195701379"
+ "0902293850442561995774628930418082115864728330723111110174368232384797709242627319756376556142528218939"
+ "7783875183123336240582938265783686836202210705597100765098627429017295706176890505466946207401105614189"
+ "2784165813507235148683348014201150784998715061575093867666453332433607035581378251824779499939486011300"
+ "7245546797308586043310145338620953330797301627631794650975659295961069452157705404946866414340860434286"
+ "65874725802069389719375237126155948350679342167596471110676954951640992376889874630989205394080379",
10);
BigInteger e = new BigInteger("65537", 10);
RSAPublicKey publicKey = CryptoUtils.getRSAPublicKey(n, e);
JsonWebKey jwk1 = JwkUtils.fromRSAPublicKey(publicKey, KeyAlgorithm.RSA_OAEP_256.getJwaName());
assertNotNull(jwk1.getProperty(JsonWebKey.RSA_PUBLIC_EXP));
assertNull(jwk1.getProperty(JsonWebKey.RSA_PRIVATE_EXP));
RSAPublicKey privateKey2 = JwkUtils.toRSAPublicKey(jwk1);
assertEquals(privateKey2, publicKey);
}
@Test
public void testToPrivateRsaKeyWithoutE() throws Exception {
RSAPrivateKey privateKey1 =
(RSAPrivateKey)KeyManagementUtils.loadPrivateKey("org/apache/cxf/rs/security/jose/jws/alice.jks",
"password",
"alice",
"password",
null);
JsonWebKey jwk1 = JwkUtils.fromRSAPrivateKey(privateKey1, KeyAlgorithm.RSA_OAEP_256.getJwaName());
assertNotNull(jwk1.getProperty(JsonWebKey.RSA_PUBLIC_EXP));
jwk1.asMap().remove(JsonWebKey.RSA_PUBLIC_EXP);
try {
JwkUtils.toRSAPrivateKey(jwk1);
fail("JWK without the public exponent can not be converted to RSAPrivateKey");
} catch (JoseException ex) {
// expected
}
}
@Test
public void testRsaKeyThumbprint() throws Exception {
String thumbprint = JwkUtils.getThumbprint(RSA_KEY);
assertEquals("NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs", thumbprint);
}
@Test
public void testOctetKey1Thumbprint() throws Exception {
String thumbprint = JwkUtils.getThumbprint(OCTET_KEY_1);
assertEquals("7WWD36NF4WCpPaYtK47mM4o0a5CCeOt01JXSuMayv5g", thumbprint);
}
@Test
public void testOctetKey2Thumbprint() throws Exception {
String thumbprint = JwkUtils.getThumbprint(OCTET_KEY_2);
assertEquals("5_qb56G0OJDw-lb5mkDaWS4MwuY0fatkn9LkNqUHqMk", thumbprint);
}
@Test
public void testEc256KeyThumbprint() throws Exception {
String thumbprint = JwkUtils.getThumbprint(EC_256_KEY);
assertEquals("j4UYwo9wrtllSHaoLDJNh7MhVCL8t0t8cGPPzChpYDs", thumbprint);
}
@Test
public void testEc384KeyThumbprint() throws Exception {
String thumbprint = JwkUtils.getThumbprint(EC_384_KEY);
assertEquals("vZtaWIw-zw95JNzzURg1YB7mWNLlm44YZDZzhrPNetM", thumbprint);
}
@Test
public void testEc521KeyThumbprint() throws Exception {
String thumbprint = JwkUtils.getThumbprint(EC_521_KEY);
assertEquals("rz4Ohmpxg-UOWIWqWKHlOe0bHSjNUFlHW5vwG_M7qYg", thumbprint);
}
}