Quantcast

[BC-FIPS] Bouncy Castle problem

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[BC-FIPS] Bouncy Castle problem

Kamal, Murali

Hi Team,

 

Need help with Bouncy Castle FIPS version 1.0.0.

 

Below is a test program for PBESwithMD5andRC2. The program works fine with non-FIPS jar,  but gives out the following error when used with FIPS jar.

 

Approved Mode: false

Exception in thread "main" java.security.NoSuchAlgorithmException: no such algorithm: PBEWITHMD5ANDRC2-CBC for provider BCFIPS

                at sun.security.jca.GetInstance.getService(GetInstance.java:87)

                at javax.crypto.JceSecurity.getInstance(JceSecurity.java:97)

                at javax.crypto.SecretKeyFactory.getInstance(SecretKeyFactory.java:204)

                at PbesMd5Rc2Bouncy.main(PbesMd5Rc2Bouncy.java:54)

 

When I list out the provider “keys” in the fips jar, BC-FIPS lists “pbeswithmd5andrc2” as

 

  SecretKeyFactory.PBEWITHMD5ANDRC2

  Cipher.PBEWITHMD5ANDRC2-CBC

  SecretKeyFactory.PBEWITHMD5ANDRC2 ImplementedIn

  Cipher.PBEWITHMD5ANDRC2-CBC ImplementedIn

  Alg.Alias.Cipher.PBEWITHMD5ANDRC2

 

Using the bcfips-1.0.0 version.

 

Please note that the approvedOnly mode is set to false.

 

Could you please let us know the settings(IV etc) that we are missing with BC-FIPS module.

 

Regards,

Murali.

 

Code-Snippet:

 

 

public class PBES_MD5_RC2

{

    public static void main(

        String[]    args)

        throws Exception

    {

 

        // PBES-MD5-RC2-64bitkey-1000iterations

 

        char[]  password = "secret".toCharArray();

        byte[]  cleartext = "hello world".getBytes("UTF-8");

        

       

        Security.addProvider(new BouncyCastleFipsProvider());

        //Security.addProvider(new BouncyCastleProvider());

      

        System.out.println("Approved Mode: " + CryptoServicesRegistrar.isInApprovedOnlyMode());

/*

        Provider p = Security.getProvider("BCFIPS");

        for (Enumeration e = p.keys(); e.hasMoreElements();)

              System.out.println("\t" + e.nextElement());

*/

       

        PBEKeySpec pbeKeySpec;

        PBEParameterSpec pbeParamSpec;

        SecretKeyFactory keyFac;

              

 

        byte[] salt = {(byte)0x76, (byte)0x39, (byte)0x33, (byte)0x04, (byte)0x65, (byte)0x27, (byte)0x15, (byte)0x4a };

        int iter = 1000;

 

      

        pbeKeySpec = new PBEKeySpec(password, salt, iter);

        keyFac = SecretKeyFactory.getInstance("PBEWITHMD5ANDRC2-CBC", "BCFIPS");

        //keyFac = SecretKeyFactory.getInstance("PBEWITHMD5ANDRC2-CBC", "BC");

 

 

        Key pbeKey = keyFac.generateSecret(pbeKeySpec);

        Cipher pbeCipher = Cipher.getInstance("PBEWITHMD5ANDRC2-CBC", "BCFIPS");

        //Cipher pbeCipher = Cipher.getInstance("PBEWITHMD5ANDRC2-CBC", "BC");

 

 

        pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey);

        byte[] ciphertext = new byte[pbeCipher.getOutputSize(cleartext.length)];

        int ctLength = pbeCipher.update(cleartext, 0, cleartext.length, ciphertext, 0);

        ctLength += pbeCipher.doFinal(ciphertext, ctLength);

      

 

        byte[] encodedBytes = Base64.getEncoder().encode(ciphertext);

        String base64cipher = new String(encodedBytes);

        System.out.println("passoword: " + new String(password));

        System.out.println("cleartext: " + new String(cleartext));

        System.out.println("base64 ciphertext: " + base64cipher);

       

 

        byte[] decbytes = Base64.getDecoder().decode(base64cipher);

 

        pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey);

        byte[] retext = new byte[pbeCipher.getOutputSize(decbytes.length)];

        int ptLength = pbeCipher.update(decbytes, 0, decbytes.length, retext, 0);

        ptLength += pbeCipher.doFinal(retext, ptLength);

        System.out.println("retext: " + new String(retext));

 

 

    }

}

 

 

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [BC-FIPS] Bouncy Castle problem

David Hook-3

Okay, PBE has a bit of an odd history in the JCE, it evolved over several releases as different algorithms were added internally at SUN - the original version didn't consider that PBE might also be used to generate IVs which lead to the common pattern in BC of having factories which included the full algorithm details for the cipher as well (the -CBC) and not just the key generation component. The end result of this is also that occasionally people get more than they bargain for especially if they mistakenly use a key factory and PBE parameters in the wrong way, or use a mode that requires an IV and not realize one might have been dragged in by the key factory step.

We tried to get this rationalized with the FIPS release and are in the process of making sure the equivalent can be done in regular BC (while trying to keep the old ways working as well...)

In this case, where the PBE algorithm is tied up with the cipher and the mode used, in BCFIPS use:

public static void main(
     String[]    args)
     throws Exception
 {
     // PBES-MD5-RC2-64bitkey-1000iterations

     char[]  password = "secret".toCharArray();

     byte[]  cleartext = "hello world".getBytes("UTF-8");

     Security.addProvider(new BouncyCastleFipsProvider());

     //Security.addProvider(new BouncyCastleProvider());

     System.out.println("Approved Mode: " + CryptoServicesRegistrar.isInApprovedOnlyMode());

     PBEParameterSpec pbeParamSpec;

     byte[] salt = {(byte)0x76, (byte)0x39, (byte)0x33, (byte)0x04, (byte)0x65, (byte)0x27, (byte)0x15, (byte)0x4a };

     int iter = 1000;

     Cipher pbeCipher = Cipher.getInstance("PBEWITHMD5ANDRC2-CBC", "BCFIPS");
     
     pbeParamSpec = new PBEParameterSpec(salt, iter);
     pbeCipher.init(Cipher.ENCRYPT_MODE, new PBKDF1Key(password, PasswordConverter.ASCII), pbeParamSpec);

     byte[] ciphertext = new byte[pbeCipher.getOutputSize(cleartext.length)];

     int ctLength = pbeCipher.update(cleartext, 0, cleartext.length, ciphertext, 0);

     ctLength += pbeCipher.doFinal(ciphertext, ctLength);

     byte[] encodedBytes = Base64.encode(ciphertext, 0, ctLength);

     String base64cipher = new String(encodedBytes);

     System.out.println("passoword: " + new String(password));
     System.out.println("cleartext: " + new String(cleartext));
     System.out.println("base64 ciphertext: " + base64cipher);

     byte[] decbytes = Base64.decode(base64cipher);

     pbeCipher.init(Cipher.DECRYPT_MODE, new PBKDF1Key(password, PasswordConverter.ASCII), pbeParamSpec);

     byte[] retext = new byte[pbeCipher.getOutputSize(decbytes.length)];

     int ptLength = pbeCipher.update(decbytes, 0, decbytes.length, retext, 0);

     ptLength += pbeCipher.doFinal(retext, ptLength);

     System.out.println("retext: " + new String(retext, 0, ptLength));
 }

In regular BC the same (which is the preferred approach) can be done as:

public static void main(
     String[]    args)
     throws Exception

 {
     char[]  password = "secret".toCharArray();

     byte[]  cleartext = "hello world".getBytes("UTF-8");

     Security.addProvider(new BouncyCastleProvider());
     
     PBEKeySpec pbeKeySpec;

     PBEParameterSpec pbeParamSpec;

     SecretKeyFactory keyFac;

     CharToByteConverter ascii = new CharToByteConverter()
                             {
                                 public String getType()
                                 {
                                     return "ASCII";
                                 }

                                 public byte[] convert(char[] password)
                                 {
                                     return Strings.toByteArray(password);     // just drop hi-order byte.
                                 }
                             };



     byte[] salt = {(byte)0x76, (byte)0x39, (byte)0x33, (byte)0x04, (byte)0x65, (byte)0x27, (byte)0x15, (byte)0x4a };

     int iter = 1000;

     Cipher pbeCipher = Cipher.getInstance("PBEWITHMD5ANDRC2-CBC", "BC");

     pbeParamSpec = new PBEParameterSpec(salt, iter);
     pbeCipher.init(Cipher.ENCRYPT_MODE, new PBKDF1Key(password, ascii), pbeParamSpec);

     byte[] ciphertext = new byte[pbeCipher.getOutputSize(cleartext.length)];

     int ctLength = pbeCipher.update(cleartext, 0, cleartext.length, ciphertext, 0);

     ctLength += pbeCipher.doFinal(ciphertext, ctLength);

     byte[] encodedBytes = Base64.encode(ciphertext, 0, ctLength);

     String base64cipher = new String(encodedBytes);

     System.out.println("passoword: " + new String(password));
     System.out.println("cleartext: " + new String(cleartext));
     System.out.println("base64 ciphertext: " + base64cipher);


     byte[] decbytes = Base64.decode(base64cipher);

     pbeCipher.init(Cipher.DECRYPT_MODE, new PBKDF1Key(password, ascii), pbeParamSpec);

     byte[] retext = new byte[pbeCipher.getOutputSize(decbytes.length)];

     int ptLength = pbeCipher.update(decbytes, 0, decbytes.length, retext, 0);

     ptLength += pbeCipher.doFinal(retext, ptLength);

     System.out.println("retext: " + new String(retext, 0, ptLength));
 }
We'll add the PasswordConverter class in the next release of BC...

Regards,

David

On 10/03/17 22:58, Kamal, Murali wrote:

Hi Team,

 

Need help with Bouncy Castle FIPS version 1.0.0.

 

Below is a test program for PBESwithMD5andRC2. The program works fine with non-FIPS jar,  but gives out the following error when used with FIPS jar.

 

Approved Mode: false

Exception in thread "main" java.security.NoSuchAlgorithmException: no such algorithm: PBEWITHMD5ANDRC2-CBC for provider BCFIPS

                at sun.security.jca.GetInstance.getService(GetInstance.java:87)

                at javax.crypto.JceSecurity.getInstance(JceSecurity.java:97)

                at javax.crypto.SecretKeyFactory.getInstance(SecretKeyFactory.java:204)

                at PbesMd5Rc2Bouncy.main(PbesMd5Rc2Bouncy.java:54)

 

When I list out the provider “keys” in the fips jar, BC-FIPS lists “pbeswithmd5andrc2” as

 

  SecretKeyFactory.PBEWITHMD5ANDRC2

  Cipher.PBEWITHMD5ANDRC2-CBC

  SecretKeyFactory.PBEWITHMD5ANDRC2 ImplementedIn

  Cipher.PBEWITHMD5ANDRC2-CBC ImplementedIn

  Alg.Alias.Cipher.PBEWITHMD5ANDRC2

 

Using the bcfips-1.0.0 version.

 

Please note that the approvedOnly mode is set to false.

 

Could you please let us know the settings(IV etc) that we are missing with BC-FIPS module.

 

Regards,

Murali.

 

Code-Snippet:

 

 

public class PBES_MD5_RC2

{

    public static void main(

        String[]    args)

        throws Exception

    {

 

        // PBES-MD5-RC2-64bitkey-1000iterations

 

        char[]  password = "secret".toCharArray();

        byte[]  cleartext = "hello world".getBytes("UTF-8");

        

       

        Security.addProvider(new BouncyCastleFipsProvider());

        //Security.addProvider(new BouncyCastleProvider());

      

        System.out.println("Approved Mode: " + CryptoServicesRegistrar.isInApprovedOnlyMode());

/*

        Provider p = Security.getProvider("BCFIPS");

        for (Enumeration e = p.keys(); e.hasMoreElements();)

              System.out.println("\t" + e.nextElement());

*/

       

        PBEKeySpec pbeKeySpec;

        PBEParameterSpec pbeParamSpec;

        SecretKeyFactory keyFac;

              

 

        byte[] salt = {(byte)0x76, (byte)0x39, (byte)0x33, (byte)0x04, (byte)0x65, (byte)0x27, (byte)0x15, (byte)0x4a };

        int iter = 1000;

 

      

        pbeKeySpec = new PBEKeySpec(password, salt, iter);

        keyFac = SecretKeyFactory.getInstance("PBEWITHMD5ANDRC2-CBC", "BCFIPS");

        //keyFac = SecretKeyFactory.getInstance("PBEWITHMD5ANDRC2-CBC", "BC");

 

 

        Key pbeKey = keyFac.generateSecret(pbeKeySpec);

        Cipher pbeCipher = Cipher.getInstance("PBEWITHMD5ANDRC2-CBC", "BCFIPS");

        //Cipher pbeCipher = Cipher.getInstance("PBEWITHMD5ANDRC2-CBC", "BC");

 

 

        pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey);

        byte[] ciphertext = new byte[pbeCipher.getOutputSize(cleartext.length)];

        int ctLength = pbeCipher.update(cleartext, 0, cleartext.length, ciphertext, 0);

        ctLength += pbeCipher.doFinal(ciphertext, ctLength);

      

 

        byte[] encodedBytes = Base64.getEncoder().encode(ciphertext);

        String base64cipher = new String(encodedBytes);

        System.out.println("passoword: " + new String(password));

        System.out.println("cleartext: " + new String(cleartext));

        System.out.println("base64 ciphertext: " + base64cipher);

       

 

        byte[] decbytes = Base64.getDecoder().decode(base64cipher);

 

        pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey);

        byte[] retext = new byte[pbeCipher.getOutputSize(decbytes.length)];

        int ptLength = pbeCipher.update(decbytes, 0, decbytes.length, retext, 0);

        ptLength += pbeCipher.doFinal(retext, ptLength);

        System.out.println("retext: " + new String(retext));

 

 

    }

}

 

 


Loading...