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.