Why java.security.NoSuchProviderException No such provider: BC?

139,539

Solution 1

Im not very familiar with the Android sdk, but it seems that the android-sdk comes with the BouncyCastle provider already added to the security.

What you will have to do in the PC environment is just add it manually,

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

if you have access to the policy file, just add an entry like:

security.provider.5=org.bouncycastle.jce.provider.BouncyCastleProvider 

Notice the .5 it is equal to a sequential number of the already added providers.

Solution 2

You can add security provider by editing java.security with using following code with creating static block:

static {
    Security.addProvider(new BouncyCastleProvider());
}

If you are using maven project, then you will have to add dependency for BouncyCastleProvider as follows in pom.xml file of your project.

<dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.47</version>
</dependency>

If you are using normal java project, then you can add download bcprov-jdk15on-147.jar from the link given below and edit your classpath.

http://www.java2s.com/Code/Jar/b/Downloadbcprovextjdk15on147jar.htm

Solution 3

you can add security provider by editing java.security by adding security.provider.=org.bouncycastle.jce.provider.BouncyCastleProvider

or add a line in your top of your class

Security.addProvider(new BouncyCastleProvider());

you can use below line to specify provider while specifying algorithms

Cipher cipher = Cipher.getInstance("AES", "SunJCE");

if you are using other provider like Bouncy Castle then

Cipher cipher =  Cipher.getInstance("AES", "BC");

Solution 4

My experience with this was that when I had this in every execution it was fine using the provider as a string like this

Security.addProvider(new BounctCastleProvider());
new JcaPEMKeyConverter().setProvider("BC");

But when I optimized and put the following in the constructor:

   if(bounctCastleProvider == null) {
      bounctCastleProvider = new BouncyCastleProvider();
    }

    if(Security.getProvider(bouncyCastleProvider.getName()) == null) {
      Security.addProvider(bouncyCastleProvider);
    }

Then I had to use provider like this or I would get the above error:

new JcaPEMKeyConverter().setProvider(bouncyCastleProvider);

I am using bcpkix-jdk15on version 1.65

Solution 5

For those who are using web servers make sure that the bcprov-jdk16-145.jar has been installed in you servers lib, for weblogic had to put the jar in:

<weblogic_jdk_home>\jre\lib\ext
Share:
139,539

Related videos on Youtube

jacknad
Author by

jacknad

Electrical Engineer with experience in microprocessor hardware design, ASM, PL/M, C/C++, C#, Android, Linux, Python, and Java. First high school radio design burst into flames during the demo. First software program was FORTRAN on punch cards. Worked in FL, IL, ND, NJ, TX, VA, and WA.

Updated on July 05, 2022

Comments

  • jacknad
    jacknad almost 2 years

    The jar (bcprov-jdk16-145.jar) has been added to the project, Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()) has been added to the class, and BouncyCastleProvider.PROVIDER_NAME does return "BC" but AesFileIo.writeFile() still throws java.security.NoSuchProviderException No such provider: BC. Any ideas?

    import java.io.FileOutputStream;
    import java.io.InputStreamReader;
    import java.io.ObjectOutputStream;
    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    public class AesFileIo {
    
        private static final String AES_ALGORITHM = "AES/CTR/NoPadding";
        private static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
        private static final byte[] AES_KEY_128 = { // Hard coded for now
            78, -90, 42, 70, -5, 20, -114, 103,
            -99, -25, 76, 95, -85, 94, 57, 54};
        private static final byte[] IV = { // Hard coded for now
            -85, -67, -5, 88, 28, 49, 49, 85,
            114, 83, -40, 119, -65, 91, 76, 108};
        private static final SecretKeySpec secretKeySpec =
                new SecretKeySpec(AES_KEY_128, "AES");
        private static final IvParameterSpec ivSpec = new IvParameterSpec(IV);
    
        public void AesFileIo() {
            Security.addProvider(new org.bouncycastle.jce.provider
                    .BouncyCastleProvider());
        }
    
        public void writeFile(String fileName, String theFile) {
            try {
                Cipher cipher = Cipher.getInstance(AES_ALGORITHM, PROVIDER);
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
                byte[] encrypted = cipher.doFinal(theFile.getBytes());
                ObjectOutputStream os = new ObjectOutputStream(
                    new FileOutputStream(fileName));
                os.write(encrypted);
                os.flush();
                os.close();
            } catch (Exception e) {
                StackTraceElement se = new Exception().getStackTrace()[0];
                System.err.println(se.getFileName() + " " + se.getLineNumber()
                        + " " + e);
            }
        }
    }
    
  • jacknad
    jacknad over 13 years
    Does this need to be manually added to the PC environment for all PCs that run this application or can this be accomplished programmatically (bcprov-jdk16-145.jar has already been added to the project)?
  • Garis M Suero
    Garis M Suero over 13 years
    You will need to code the Security.addProvider in your code, just to make sure it is loaded, and maybe you will need to add your jar to your project :)
  • jacknad
    jacknad over 13 years
    I have added private static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME (which resolves to "BC") as a field in the code, and I have added the jar to the project but continue to get java.security.NoSuchProviderException: No such provider: BC. I'll edit my original question by including the entire class.
  • jacknad
    jacknad over 13 years
    Got it. Needed Cipher cipher = Cipher.getInstance(AES_ALGORITHM); rather than Cipher cipher = Cipher.getInstance(AES_ALGORITHM, PROVIDER);. I suppose the Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); forces the "BC" and the Cipher.getInstance(AES_ALGORITHM, PROVIDER); is just not understood in this context.
  • Broken_Window
    Broken_Window about 8 years
    Works when BC 1.38 throws a "java.security.NoSuchProviderException: no such provider: BC" in the line 'CertStore certStore = cmssignedData.getCertificatesAndCRLs("Collection", "BC");'