Чому java.security.NoSuchProviderException Немає такого постачальника: BC?


77

Jar (bcprov-jdk16-145.jar) додано до проекту, Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())додано до класу і BouncyCastleProvider.PROVIDER_NAMEповертає "BC", але AesFileIo.writeFile () все одно кидає java.security.NoSuchProviderException No such provider: BC. Будь-які ідеї?

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);
        }
    }
}

Будь ласка , зверніться за посиланням, stackoverflow.com/questions/39097099 / ...
varotariya vajsi

Відповіді:


129

Я не дуже знайомий з Android sdk, але, схоже, він android-sdkпостачається з BouncyCastleпостачальником, який вже доданий до безпеки.

Що вам потрібно буде зробити в середовищі ПК, це просто додати його вручну,

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

якщо у вас є доступ до policyфайлу, просто додайте запис, наприклад:

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

Зверніть увагу, що .5воно дорівнює послідовному номеру вже доданих постачальників.


Чи потрібно це додавати вручну до середовища ПК для всіх ПК, на яких запущена ця програма, чи це можна зробити програмним способом (bcprov-jdk16-145.jar вже додано до проекту)?
jacknad

2
Вам потрібно буде закодувати код Security.addProviderу своєму коді, лише щоб переконатися, що він завантажений, і, можливо, вам доведеться додати свій jarдо свого проекту :)
Гаріс М Суеро

Я додав private static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME(що перетворюється на "BC") як поле в коді, і додав jar до проекту, але продовжую отримувати java.security.NoSuchProviderException: No such provider: BC. Я відредагую своє оригінальне запитання, включивши весь клас.
jacknad

Зрозумів. Потрібно, Cipher cipher = Cipher.getInstance(AES_ALGORITHM);а не Cipher cipher = Cipher.getInstance(AES_ALGORITHM, PROVIDER);. Я припускаю, що Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());сили "до нашої ери" і Cipher.getInstance(AES_ALGORITHM, PROVIDER);Росії просто не зрозумілі в цьому контексті.
jacknad

Працює, коли BC 1.38 викидає "java.security.NoSuchProviderException: немає такого постачальника: BC" у рядку 'CertStore certStore = cmssignedData.getCertificatesAndCRLs ("Колекція", "BC");'
Broken_Window

14

Ви можете додати постачальника безпеки, відредагувавши java.security, додавши security.provider. = org.bouncycastle.jce.provider.BouncyCastleProvider

або додайте рядок у верхній частині вашого класу

Security.addProvider(new BouncyCastleProvider());

Ви можете використовувати рядок нижче, щоб вказати постачальника, вказуючи алгоритми

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

якщо ви використовуєте іншого постачальника, як Bouncy Castle, тоді

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

14

Ви можете додати постачальника безпеки, відредагувавши java.security за допомогою наступного коду зі створенням статичного блоку:

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

Якщо ви використовуєте проект maven , то вам доведеться додати залежність для BouncyCastleProvider, як показано у файлі pom.xml вашого проекту.

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

Якщо ви використовуєте звичайний java-проект , ви можете додати файл bcprov-jdk15on-147.jar за посиланням, наведеним нижче, та відредагувати шлях до класу .

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


1

Для тих, хто використовує веб-сервери, переконайтеся, що bcprov-jdk16-145.jar встановлений у вашій бібліотеці серверів, для weblogic потрібно було помістити банку в:

<weblogic_jdk_home>\jre\lib\ext

1

Мій досвід роботи з цим полягав у тому, що коли у мене це було при кожному виконанні, було добре використовувати постачальника як такий рядок

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

Але коли я оптимізував і помістив у конструктор наступне:

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

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

Тоді мені довелося використовувати подібний постачальник, інакше я отримав би вищевказану помилку:

new JcaPEMKeyConverter().setProvider(bouncyCastleProvider);

Я використовую bcpkix-jdk15on версії 1.65

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.