bouncycastle 错误 "JCE cannot authenticate the provider BC" "jar-with-dependencies"
bouncycastle error "JCE cannot authenticate the provider BC" with "jar-with-dependencies"
我正在创建一个 java 独立应用程序,它使用 bouncycastle。 在 eclipse 中一切正常。我正在创建一个 jar,其依赖项 如 this。
当我运行申请时"java -jar myapp-0.0.1-SNAPSHOT-jar-with-dependencies.jar".
我收到以下错误:
java.io.IOException: exception encrypting data - java.lang.SecurityException: JCE cannot authenticate the provider BC
我的代码:
Security.addProvider(new BouncyCastleProvider());
String keystoreDirectory = "C:/myapp/security";
File file = new File(keystoreDirectory + "/" + PRIVATE_KEY_FILE);
if (!file.isFile()) {
try {
Configuration idOrganization = configurationBoundary.find(Configuration.ID_ORGANIZATION);
KeyStore store = KeyStore.getInstance("PKCS12", SECURITY_PROVIDER);
char[] password = KEY.toCharArray();
store.load(null, password);
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", SECURITY_PROVIDER);
keyPairGenerator.initialize(2048);
KeyPair pair = keyPairGenerator.generateKeyPair();
X500Name issuer = new X500Name("CN=" + idOrganization.getProperty());
BigInteger serial = BigInteger.valueOf(new SecureRandom().nextLong());
Date notBefore = new Date(System.currentTimeMillis() - 10000);
Date notAfter = new Date(System.currentTimeMillis() + 24L * 3600 * 1000 * 365);
X500Name subject = new X500Name("CN=" + idOrganization.getProperty());
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(pair.getPublic().getEncoded());
X509v3CertificateBuilder builder = new X509v3CertificateBuilder(issuer, serial, notBefore, notAfter, subject, publicKeyInfo);
ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(SECURITY_PROVIDER).build(pair.getPrivate());
X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER).getCertificate(builder.build(sigGen));
store.setKeyEntry(idOrganization.getProperty(), pair.getPrivate(), null, new java.security.cert.Certificate[]{cert});
try (FileOutputStream fos = new FileOutputStream(file)) {
store.store(fos, password); //Error here
}
} catch (Exception ex) {
logger.error("Keystore creation error", ex);
}
}
有什么想法吗?
谢谢。
不幸的是,JCE 需要对带有 Bouncy Castle 的 JAR 进行签名,而创建可执行 jar 会破坏它。准备单独运送 BouncyCastle jar。
您实际上可以使用 Spring Boot 或类似的东西 - 它将 jars 嵌入到 fat jar 中,然后解压并加载它们。或者类似 Spring 靴子的东西。
Bouncycastle jar 必须签名,不能放在 fat jar 里面。
您可以单独运送它并为此使用 maven-shade-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<artifactSet>
<excludes>
<exclude>org.bouncycastle:*:*:*</exclude>
</excludes>
</artifactSet>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.example.Main</Main-Class>
<Class-Path>. ./lib/bcprov-jdk16-1.46.jar</Class-Path>
</manifestEntries>
</transformer>
</transformers>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>fat</shadedClassifierName>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
在 ManifestResourceTransformer 中,您定义了 bouncycastle jar 依赖项的类路径。
问题是 BouncyCastle jar 已签名,必须保持原样。对我来说,在 Maven 中包含范围为 'provided' 的依赖项有效。
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.55</version>
<scope>provided</scope>
</dependency>
我已经用这个插件打包了一个fat jar
https://github.com/nthuemmel/executable-packer-maven-plugin
它在一个胖罐子里使用了很好的着色和使用充气城堡
我正在创建一个 java 独立应用程序,它使用 bouncycastle。 在 eclipse 中一切正常。我正在创建一个 jar,其依赖项 如 this。
当我运行申请时"java -jar myapp-0.0.1-SNAPSHOT-jar-with-dependencies.jar".
我收到以下错误:
java.io.IOException: exception encrypting data - java.lang.SecurityException: JCE cannot authenticate the provider BC
我的代码:
Security.addProvider(new BouncyCastleProvider());
String keystoreDirectory = "C:/myapp/security";
File file = new File(keystoreDirectory + "/" + PRIVATE_KEY_FILE);
if (!file.isFile()) {
try {
Configuration idOrganization = configurationBoundary.find(Configuration.ID_ORGANIZATION);
KeyStore store = KeyStore.getInstance("PKCS12", SECURITY_PROVIDER);
char[] password = KEY.toCharArray();
store.load(null, password);
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", SECURITY_PROVIDER);
keyPairGenerator.initialize(2048);
KeyPair pair = keyPairGenerator.generateKeyPair();
X500Name issuer = new X500Name("CN=" + idOrganization.getProperty());
BigInteger serial = BigInteger.valueOf(new SecureRandom().nextLong());
Date notBefore = new Date(System.currentTimeMillis() - 10000);
Date notAfter = new Date(System.currentTimeMillis() + 24L * 3600 * 1000 * 365);
X500Name subject = new X500Name("CN=" + idOrganization.getProperty());
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(pair.getPublic().getEncoded());
X509v3CertificateBuilder builder = new X509v3CertificateBuilder(issuer, serial, notBefore, notAfter, subject, publicKeyInfo);
ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(SECURITY_PROVIDER).build(pair.getPrivate());
X509Certificate cert = new JcaX509CertificateConverter().setProvider(SECURITY_PROVIDER).getCertificate(builder.build(sigGen));
store.setKeyEntry(idOrganization.getProperty(), pair.getPrivate(), null, new java.security.cert.Certificate[]{cert});
try (FileOutputStream fos = new FileOutputStream(file)) {
store.store(fos, password); //Error here
}
} catch (Exception ex) {
logger.error("Keystore creation error", ex);
}
}
有什么想法吗? 谢谢。
不幸的是,JCE 需要对带有 Bouncy Castle 的 JAR 进行签名,而创建可执行 jar 会破坏它。准备单独运送 BouncyCastle jar。
您实际上可以使用 Spring Boot 或类似的东西 - 它将 jars 嵌入到 fat jar 中,然后解压并加载它们。或者类似 Spring 靴子的东西。
Bouncycastle jar 必须签名,不能放在 fat jar 里面。 您可以单独运送它并为此使用 maven-shade-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<artifactSet>
<excludes>
<exclude>org.bouncycastle:*:*:*</exclude>
</excludes>
</artifactSet>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.example.Main</Main-Class>
<Class-Path>. ./lib/bcprov-jdk16-1.46.jar</Class-Path>
</manifestEntries>
</transformer>
</transformers>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>fat</shadedClassifierName>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
在 ManifestResourceTransformer 中,您定义了 bouncycastle jar 依赖项的类路径。
问题是 BouncyCastle jar 已签名,必须保持原样。对我来说,在 Maven 中包含范围为 'provided' 的依赖项有效。
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.55</version>
<scope>provided</scope>
</dependency>
我已经用这个插件打包了一个fat jar
https://github.com/nthuemmel/executable-packer-maven-plugin
它在一个胖罐子里使用了很好的着色和使用充气城堡