JCEHandler can't find specified provider class

40 views
Skip to first unread message

Babatunde Oyenekan

unread,
Mar 8, 2023, 3:34:53 AM3/8/23
to jPOS Users

Hello JPOS team , 

I want to generate a new Pin key using the Master key , the code throws error and says that JCEHandler could not find the specified provider class . Here is the code snippet :

.............................................................................................................................

String hexMaster = TERMINAL_CTMK;

    byte[] keydata = h2b(hexMaster);

    String zonepin = null;

    SecretKey encryptedMaster = new SecretKeySpec(keydata, "DESede");

    

     try 

     

           {

       

       JCEHandler jceHandler = new JCEHandler("DES");

       Key newkey =  jceHandler.generateDESKey(SMAdapter.LENGTH_DES3_2KEY);

       byte[] enkey = jceHandler.encryptDESKey(SMAdapter.LENGTH_DES3_2KEY, newkey, encryptedMaster);

       byte[] component_2 = h2b(COMPONENT_2);

    

       byte[] wholecheckvalue = jceHandler.encryptData(component_2, newkey);

       

       byte[] checkvalue = ISOUtil.trim(wholecheckvalue, 4);

       

       zonepin = b2h(enkey) + b2h(checkvalue);

       

       logger.info("Generating Pin Key to processor" + zonepin );

       

    }

       

    catch(Exception ex) 

        

            {

    

    logger.error("error generating zone pin key: "+ex.getMessage()+"\n"+Arrays.toString(ex.getStackTrace()));

    

        }

    

        return zonepin;

    

    }


.................................................................

   

Mark Salter

unread,
Mar 8, 2023, 4:42:38 AM3/8/23
to jpos-...@googlegroups.com
Sharing the exception detail might help someone guide.


-- 
Mark


Sent from Proton Mail mobile



-------- Original Message --------
--
--
jPOS is licensed under AGPL - free for community usage for your open-source project. Licenses are also available for commercial usage. Please support jPOS, contact: sa...@jpos.org
---
You received this message because you are subscribed to the Google Groups "jPOS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jpos-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jpos-users/463d9c85-1b2e-46e8-bdd0-a8c2a22184a0n%40googlegroups.com.
signature.asc

Babatunde Oyenekan

unread,
Mar 8, 2023, 5:55:54 AM3/8/23
to jPOS Users
I refactored code t this :


        JCEHandler jceHandler = new JCEHandler(DESedeKeySpec.class.getName());

       newkey =  jceHandler.generateDESKey(SMAdapter.LENGTH_DES3_2KEY);



 java.lang.InstantiationException: javax.crypto.spec.DESedeKeySpec

[com.tm30.agencybanking.terminalsystem.Crytpo.CustomJCEHandler.<init>(CustomJCEHandler.java:31), com.tm30.agencybanking.terminalsystem.Crytpo.CCrypto.generateZonemaskterKey(CCrypto.java:223), com.tm30.agencybanking.terminalsystem.controller.TerminalController.getKey(TerminalController.java:28), java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104), java.base/java.lang.reflect.Method.invoke(Method.java:577), org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207), org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152), org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117), org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884).......


Andrés Alcarraz

unread,
Mar 8, 2023, 3:37:08 PM3/8/23
to jpos-...@googlegroups.com

Hi Babatunde,

Firstly, let me suggest a better way to log a stack trace:


            logger.error("error generating zone pin key: ", ex);

The stack trace will be printed one line at a time and be more legible.

Secondly, I don’t understand what are you are trying to achieve by passing DESedeKeySpec.class.getName() to the JCEHandler constructor, since DESedeKeySpec is not an instance of java.security.Provider and it doesn’t have a default constructor. This last thing is what is causing the exception, but even if it didn’t, it would fail later because of the other thing (not being a security provider)

And finally, it seems you are working with a locally modified version of JCEHandler why do you want that?

Best regards.

Andrés.

Babatunde Oyenekan

unread,
Mar 9, 2023, 4:49:05 AM3/9/23
to jPOS Users
Thanks to everyone , I passed this DESedeKeySpec.class.getName() to JCEhandler instantiation because the constructor needs a provider class name passed . This is what I am trying to achieve :

I want to generate a KWP so that I can send it to Post bridge when a Pin Key request field 70 value 101 is sent to my Acquirer host app . 

- I have been provided with two keys Component 1 : 3DE......................................9A6 and component 2 : 0000000000000 (Component 2 is all zeros 16bits and 32Chars) . 

-I XORed both keys so as to get the Zone Master Key ( After XOR operation I got same value for Component key 1).

- Generating key using 3des DES/ECD/NoPadding returned error saying wrong key size : 

                 SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");

     SecretKey key = factory.generateSecret(new DESedeKeySpec(keydata));


                //keydata is the value got after xoring Component 1 and 2 


-  After concatenating Component 1 and Component 2 , I was able to generate Keys . 



I want to be sure that I am doing the right thing , I've been stuck on this part for more than a week , I will really appreciate an input as to where I am doing the wrong thing please . 


-Also I got Pin key after making a PIN key request to post bridge , what do I do with this PIN key ? am I just checking the Key check value to ensure what  postbridge has is same as what we have on our end ? 


Thanks in advance .  


Andrés Alcarraz

unread,
Mar 11, 2023, 10:53:03 AM3/11/23
to jpos-...@googlegroups.com

I passed this DESedeKeySpec.class.getName() to JCEhandler instantiation because the constructor needs a provider class name passed

Thing is, DESedeKeySpec is not a provider class. You can see how it is instantiated in the jPOS code that uses it:


            try {
                if (jceProviderClassName == null || jceProviderClassName.isEmpty()) {
                    evt.addMessage("No JCE Provider specified. Attempting to load default provider (SunJCE).");
                    jceProviderClassName = "com.sun.crypto.provider.SunJCE";
                }
                provider = (Provider)Class.forName(jceProviderClassName).newInstance();
                Security.addProvider(provider);
                evt.addMessage("name", provider.getName());
            } catch (Exception e) {
                evt.addMessage(e);
                throw  new SMException("Unable to load jce provider whose class name is: "
                        + jceProviderClassName);
            } finally {
                Logger.log(evt);
            }
            jceHandler = new JCEHandler(provider);

You can see there, the default value, but moreover, why don’t you use the higher level class JCESecurityModule for what you are trying? And also, you didn’t answer why you are using a customized version of that class instead of using the provided by jPOS.

I want to generate a KWP so that I can send it to Post bridge when a Pin Key request field 70 value 101 is sent to my Acquirer host app . 

- I have been provided with two keys Component 1 : 3DE......................................9A6 and component 2 : 0000000000000 (Component 2 is all zeros 16bits and 32Chars) . 

-I XORed both keys so as to get the Zone Master Key ( After XOR operation I got same value for Component key 1).

Yes, a xor with a zero is an identity operation.

You would be better by using the SMAdapter for doing this, please take a look at https://github.com/jpos/jPOS/wiki/HSM_basics, and also how to run the q2 cli in section 7.1.1 of jPOS programmer’s Guide to run smconsole --help and check the different options. This is valid only for testing, for production you would surely need to use a real HSM.

- Generating key using 3des DES/ECD/NoPadding returned error saying wrong key size : 

                 SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");

     SecretKey key = factory.generateSecret(new DESedeKeySpec(keydata));


                //keydata is the value got after xoring Component 1 and 2 


-  After concatenating Component 1 and Component 2 , I was able to generate Keys . 



I want to be sure that I am doing the right thing , I've been stuck on this part for more than a week , I will really appreciate an input as to where I am doing the wrong thing please . 


-Also I got Pin key after making a PIN key request to post bridge , what do I do with this PIN key ? am I just checking the Key check value to ensure what  postbridge has is same as what we have on our end ? 



You had the clear keys, so the first thing you have to do is import it to the lmks, that’s the form key (FK) command of the smconsole. It will perform the xor for you, if I remember correctly, you just need to pass the number of components you have. That isn’t usually performed in your code, but has to be performed once, and then use the imported key throughout your code to import the key that you got from Postilion. And you would use that key, to translate the pin blocks to your zone key for validation if you are an issuer. Or to translate the PIN blocks captured by the terminal to the postilion key if you are an acquirer.

Crypto is usually not an easy matter to get right at the first take, so it is not advised to try code without first understanding all the concepts. Sadly I couldn’t find more links to more places that discuss that with more detail to share with you.

Regards.

Andrés.

Reply all
Reply to author
Forward
0 new messages