FYI,
https://issues.apache.org/jira/browse/CXF-6993

so that CEK does not have to be manually created in case of >1 recipients

Sergey

On 04/08/16 14:30, Sergey Beryozkin wrote:
I've updated JweUtils a bit as mentioned below and the wiki:

https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+JOSE#JAX-RSJOSE-JWEJSON


(re-organized the code, added extra comments). IMHO it should be much
easier to read now

Sergey
On 04/08/16 12:43, Sergey Beryozkin wrote:
Hi

For some reasons this email was moved to my reader's spam folder.

Please see comments below:
On 28/07/16 09:38, Socrates wrote:
Hi,

I have the following sample code that generates compact encoded output:

@Test
public void testShortFormatEncodingExample() throws Exception {
InputStream publicKeyStream =
getClass().getResourceAsStream("test.pem");
byte[] pemKey = IOUtils.toByteArray(publicKeyStream);

PEMReader pemReader = new PEMReader(new InputStreamReader(new
ByteArrayInputStream(pemKey)));
KeyPair keyPair = (KeyPair) pemReader.readObject();

PublicKey publicKey = keyPair.getPublic();

JweEncryptionProvider encrypter =
JweUtils.createJweEncryptionProvider(publicKey,
KeyAlgorithm.RSA_OAEP_256, ContentAlgorithm.A128GCM, null);
String encrypted =
encrypter.encrypt(CONTENT.getBytes(StandardCharsets.UTF_8), null);
System.out.println(encrypted);
}

And it is generating an output similar to:

eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIn0.RWG-
90nILhlBELaC7HANazRS5OAqoJV5lzMYX_96ZGCuWLWNR7xxuVyr6
uYkTPyesPHfJ4Byye47a5RLuLtCIi85LPECswJ7ADboXgyMyk_rJy4_B
xVEwjmnWhzOImlBbtHoQBLE8vPAs9DkHmt5cWMpWojkKmsXrjOOz
hSP85FdalmQlC5rifgPUkNkSP3zTsAokJofIw93D17Q8jYQx5ByCaAXb
5Ygla5xvKn8JNnkWNNqrSmsPQe2NuPBq-csKGDjFOIFlHhE7s2n68H
682tsLXD3wcGDd-ywTxMcTzp_MOJRMe-x67FzDNFEVRcHKDtI3ULv
aHuw65A9d24o6A.1J7oFaJkZCgPQwtt.bW6rEcGb9I7V13iEiQ.as6_TZ
ia3dCP9pQoOGymfA

I wanted to convert this to generate JWE JSON output, but the example
on http://cxf.apache.org/docs/jax-rs-jose.html#JAX-RSJOSE-JWEJSON as
well as the test cases in
org.apache.cxf.rs.security.jose.jwe.JweJsonProducerTest are a little
bit confusing to me.

Basically in the example code in
http://cxf.apache.org/docs/jax-rs-jose.html#JAX-RSJOSE-JWEJSON:

1. What do WRAPPER_BYTES1 and WRAPPER_BYTES2 represent? Are they
public keys for two different recipients? Why are they so short (i.e.
16 bytes each)? A public key that I am using for testing purposes is
about 280 bytes as reported by
java.security.publicKey.getEncoded().length. What are wrapperKey1 and
wrapperKey2 representing?

final String text = "The true sign of intelligence is not knowledge
but imagination.";
SecretKey wrapperKey1 =
CryptoUtils.createSecretKeySpec(WRAPPER_BYTES1, "AES");
SecretKey wrapperKey2 =
CryptoUtils.createSecretKeySpec(WRAPPER_BYTES2, "AES");

If I have two java.security.PublicKey objects, how can I convert them
to the form expected by CryptoUtils.createSecretKeySpec?

WRAPPER_BYTES1 & WRAPPER_BYTES2 represent the content key encryption
keys and as you can see it is A128KW, and the test (code sample) also
uses a separate key (CEK_BYTES) for a content encryption key.

In your JWE compact test, a CEK is auto-generated, it is not required
there. It is not required either in a JWE JSON single recipient case
but with the multiple recipients one needs to have a single CEK shared
but encrypted for different recipients by the key encryption keys

So copy & paste that test code and replace WRAPPER_BYTES1 with
PublicKey1 but only use another JweUtils method to create a PK based
KeyEncryptionProvider for RSA_OAEP_256.


2. What is the purpose of JsonWebKeysUrls? Why we didn't need it in
the compact form? Is it mandatory?

Do you refer to

sharedUnprotectedHeaders.setJsonWebKeysUrl("https://server.example.com/keys.jwks";);

?

I've just copied it from a spec example, it shows that you can set some
extra unprotected headers shared between all the recipients

3. What is the purpose of
sharedUnprotectedHeaders.setKeyEncryptionAlgorithm(KeyAlgorithm.A128KW);?

Aren't the keys encrypted with the public keys of the recipients (i.e.
wrapperKey1 and wrapperKey2)?
In that example it is No as I explained above

4. Ideally I was hoping for an API like this:

public String encrypt(String payload, List<PublicKey> publicKeys) {

}

Where payload is the content that I need to be encrypted and
publicKeys contains public keys of recipients.

That will leave few things unspecified, such as the required key & cek
algorithms and I'd like to avoid to keep defaulting all the time to some
default algo values.

JweUtils.createJweEncryptionProvider(publicKey,
KeyAlgorithm.RSA_OAEP_256, ContentAlgorithm.A128GCM, null);

(I'll add another utility method so that a compression property can be
defaulted to null)

is easy to do, and as I implied it would be sufficient for a single
JwsJson recipient case.

One only needs to create CEK manually for a case of >1 recipients to
prevent the runtime from auto-generating a new CEK per every recipient.
I've actually been planning to look at it and see if the manual setting
of CEK can also be avaoided



The example on
http://cxf.apache.org/docs/jax-rs-jose.html#JAX-RSJOSE-JWEJSON is
confusing and as it is not compilable a, makes understanding it even
more difficult.

I'll add extra comments and a Public key example a bit later on too

Sergey


Thanks in advance.






--
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Reply via email to