Forum Stats

  • 3,728,073 Users
  • 2,245,535 Discussions
  • 7,853,298 Comments

Discussions

JC 3.0.4 Signature.getInstance() 3-parameter modes

Matti Aarnio
Matti Aarnio Member Posts: 3
edited April 2018 in Java Card

The JC 3.0.4 API defines new getInstance() form for Signature, Cipher and few others.

I would like to use this Signature.getInstance(byte,byte,byte,boolean) to instantiate this kind of combination:

Signature.getInstance(MessageDigest.ALG_SHA_256, Signature.SIG_CIPHER_RSA, Cipher.PAD_PKCS1, false);

Signature.getInstance(MessageDigest.ALG_NULL, Signature.SIG_CIPHER_RSA, Cipher.PAD_PKCS1, false);

then using  sig.signPreComputedHash(...)  method to do signing.

The first form works, but puts ASN.1 DER wrapper with OID of SHA-256 around the supplied data.

I would like to use the second form supplying pre-wrapped data on a material using one of myriad digest algorithms that Java Card does not support.

Essentially I want to do with Signature API what I can do with Cipher API:

Cipher c = Cipher.getInstance(Cipger.ALG_RSA_PKCS1, false);

c.init(keyPair.getPrivate(), Cipher.MODE_ENCRYPT);

short len = c.doFinal(buffer, offset, length,  buffer, offset);

The public specifications (JC 3.0.4/3.0.5) are not telling what parameter combinations should be supported in this Signature mode.

Can anybody identify which public document describes these modes in JC 3.0.4 ?

owlstead

Answers

  • patrick.vh-Oracle
    patrick.vh-Oracle Member Posts: 17 Employee
    edited December 2017

    The signature using RSA consist in performing the following operations: encrypt(padding(hash(data)))

    • if you want to sign data already hashed and just perform the encrypt(passing(hashedData)), then use
      Signature.getInstance(MessageDigest.ALG_SHA_256, Signature.SIG_CIPHER_RSA, Cipher.PAD_PKCS1, false); to get the signature instance, then provide the hash with signature.setInitialDigest(...)

    • if you want to sign data already hashed and padded, and basically perform encrypt(hashedAndPaddedData), then you should use
      Ciper.getInstance(ALG_RSA_NOPAD, false) or Cipher.getInstance(CIPHER_RSA, PAD_NOPAD, false)
      Using Signature should not work for this operation because it performs an encryption which is subject to export controls so only supported by classes from javacardx.crypto (see note in package description)
  • Matti Aarnio
    Matti Aarnio Member Posts: 3
    edited January 2018

    The RSA case is a bit different.

    RSA is not like this:

         encrypt(padding(hash(data)))

    Instead RSA is like this:

         encrypt(padding(pkcs1wrapping(hash(data))))

    where the pkcs1wrapping adds hash OID value into sequence before hash value.

    ECDSA signature is like this:

         sign(hash(data))

    In Java Card there is no way to program the wrapper OID values for hash algorithms that will be defined even next week,

    and our application field will not want to replace every deployed card just to introduce new OIDs.

    The card is used for absolutely minimal form of the public key operation, everything else is done outside the card.

    So using a Java Card I want to upload the pkcs1wrapped hash value to the card, and the card will do signing of it, which is padding + encrypting with private key.

    Which is precisely what Cipher will do on RSA private key.

    The applet has multiple RSA and ECC keypairs generated in it, and stored internally.

    Simultaneously I want to be able to use ECC keys creating ECDSA signatures using same API:

         sig.signPrecomputedHash(hasbuf,offset,length);

    Most importantly: In the applet I want to have minimal set of Signature instances for doing there signatures. Preferably just one for RSA and other for ECDSA signatures.

    Where can I get documentation of how the parameter combinations of  Signature.getInstance(byte,byte,byte,boolean) are supposed to work?

  • owlstead
    owlstead Member Posts: 28
    edited January 2018

    Java Card is using algorithms at a relatively high level. The 3 parameter instantiator doesn't make this any different. It has just been created because defining a single byte constant for any possible combination of hash and signature generation in the end will fail; there are just too many configuration combinations possible.

    What you're currently requesting is to create a low level API so that new hash functions can be added. This is something that is currently not provided. You can of course perform the entire PKCS#1 padding and use a raw Cipher, but then you would simply be recreating PKCS#1 encoding for signature generation.

  • Matti Aarnio
    Matti Aarnio Member Posts: 3
    edited January 2018

    No, I am not interested in adding new functions.  I want to know what combinations of existing functions are supposed to be.

    Specifically I want to use same parameter sets on multiple card vendors products for same function.

    Without consistent document of what combinations should exist there is no hope to get runtime implementations to agree, and making smart card application software becomes vendor specific task.

  • 6118c29f-c598-478c-a30e-5a7e4c3d92fc
    edited April 2018

    This certainly is an issue, and it is currently not addressed completely in the Java Card specifications. You'll need to look in the various user manuals. An alternative would be to have different classes of cards, each card with a different (minimum) profile, like it is performed for Java ME. Unfortunately, that's not where we currently are.

    owlstead
This discussion has been closed.