For my project, I have to digitally sign a string and I am using bouncycastle jars for the same. The environment Details are as follows.
Weblogic 12c JSF, Primefaces Java Version : 1.7.0_45 BC Jars :
bcmail-jdk15on-152.jar, bcpkix-jdk15on-152.jar,
bcprov-ext-jdk15on-152.jar, bcprov-jdk15on-152.jar
Alternatively I have used bcprov-jdk16-1.45.jar and bcmail-jdk16-1.45.jar as well but the result is same. The Error I am getting is,
java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: SHA1WithRSAEncryption, provider: BC, class: org.bouncycastle.jce.provider.JDKDigestSignature$SHA1WithRSAEncryption)
at java.security.Provider$Service.newInstance(Provider.java:1262) ~[?:1.7.0_45]
at sun.security.jca.GetInstance.getInstance(GetInstance.java:236) ~[?:1.7.0_45]
at sun.security.jca.GetInstance.getInstance(GetInstance.java:206) ~[?:1.7.0_45]
at java.security.Signature.getInstance(Signature.java:355) ~[?:1.7.0_45]
at DigiSigner.sign(DigiSigner.java:185) [DigiSigner.class:?]
... 40 more
Caused by: java.lang.SecurityException: SHA1 digest error for org/bouncycastle/jce/provider/JDKDigestSignature$SHA1WithRSAEncryption.class
at sun.security.util.ManifestEntryVerifier.verify(ManifestEntryVerifier.java:220) ~[?:1.7.0_45]
at java.util.jar.JarVerifier.processEntry(JarVerifier.java:229) ~[?:1.7.0_45]
at java.util.jar.JarVerifier.update(JarVerifier.java:216) ~[?:1.7.0_45]
at java.util.jar.JarVerifier$VerifierStream.read(JarVerifier.java:471) ~[?:1.7.0_45]
at sun.misc.Resource.getBytes(Resource.java:124) ~[?:1.7.0_45]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:444) ~[?:1.7.0_45]
at java.net.URLClassLoader.access$100(URLClassLoader.java:71) ~[?:1.7.0_45]
at java.net.URLClassLoader$1.run(URLClassLoader.java:361) ~[?:1.7.0_45]
at java.net.URLClassLoader$1.run(URLClassLoader.java:355) ~[?:1.7.0_45]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.7.0_45]
at java.net.URLClassLoader.findClass(URLClassLoader.java:354) ~[?:1.7.0_45]
at java.lang.ClassLoader.loadClass(ClassLoader.java:425) ~[?:1.7.0_45]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) ~[?:1.7.0_45]
at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ~[?:1.7.0_45]
at java.security.Provider$Service.getImplClass(Provider.java:1279) ~[?:1.7.0_45]
at java.security.Provider$Service.newInstance(Provider.java:1237) ~[?:1.7.0_45]
... 44 more
The Code for DigiSigner.java is
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;
import sun.misc.BASE64Encoder;
@SuppressWarnings("rawtypes")
public class DigiSigner {
private String certFilePath = null;
private String pfxFilename = null;
private String jksFilename = null;
private String certPassword = null;
private char[] certPasswordArr = null;
private KeyStore keystore = null;
CMSSignedDataGenerator sgen = null;
@SuppressWarnings("unchecked")
public DigiSigner(String certificatePrefix) throws IBException{
ConfigManager config = ConfigManager.getConfigManager();
this.certFilePath = "D:/Chintan/cert_files";
this.pfxFilename = "chintan.pfx";
this.jksFilename = "chintan.jks";
this.certPassword = "abc123";
certPasswordArr = certPassword.toCharArray();
try{
this.keystore = KeyStore.getInstance("jks");
File jksFile = new File(certFilePath + "/" + jksFilename);
if(!jksFile.exists()){
this.createJKS();
}
InputStream input = new FileInputStream(certFilePath + "/" + jksFilename);
keystore.load(input, certPasswordArr);
}
catch(KeyStoreException e){
e.printStacktrace();
}
catch (NoSuchAlgorithmException e) {
e.printStacktrace();
}
catch (CertificateException e) {
e.printStacktrace();
}
catch (IOException e) {
e.printStacktrace();
}
}
@SuppressWarnings("unchecked")
public String sign(String dataToSign) throws IBException{
String signedData = null;
try {
byte[] dataToSignArr = dataToSign.getBytes();
Security.addProvider(new BouncyCastleProvider());
Enumeration e = keystore.aliases();
String alias = "";
if(e != null){
while(e.hasMoreElements()){
String n = (String)e.nextElement();
if (keystore.isKeyEntry(n)){
alias = n;
}
}
}
PrivateKey privateKey = (PrivateKey) keystore.getKey(alias, certPasswordArr);
Signature signature = Signature.getInstance("SHA1WithRSA", "BC");
signature.initSign(privateKey);
signature.update(dataToSignArr);
//Build CMS
X509Certificate cert = (X509Certificate) this.keystore.getCertificate(alias);
List certList = new ArrayList();
CMSTypedData msg = new CMSProcessableByteArray(signature.sign());
certList.add(cert);
Store certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privateKey);
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, cert));
gen.addCertificates(certs);
CMSSignedData sigData = gen.generate(msg, false);
BASE64Encoder encoder = new BASE64Encoder();
signedData = encoder.encode((byte[]) sigData.getSignedContent().getContent());
System.out.println("Signature is : " + signedData);
}
catch(KeyStoreException e){
e.printStacktrace();
}
catch (NoSuchAlgorithmException e) {
e.printStacktrace();
}
catch (NoSuchProviderException e) {
e.printStacktrace();
}
catch (CMSException e) {
e.printStacktrace();
}
catch (UnrecoverableKeyException e) {
e.printStacktrace();
}
catch (SignatureException e) {
e.printStacktrace();
}
catch (InvalidKeyException e) {
e.printStacktrace();
}
catch (CertificateEncodingException e) {
e.printStacktrace();
}
catch (OperatorCreationException e) {
e.printStacktrace();
}
return signedData;
}
public void createJKS() throws IBException{
try{
File fileIn = new File(certFilePath + "/" + pfxFilename);
File fileOut = new File(certFilePath + "/" + jksFilename);
if(!fileIn.canRead()){
throw new IBException("Unable to access input keystore: " + fileIn.getPath());
}
if(fileOut.exists() && !fileOut.canWrite()){
throw new IBException("Output file is not writable: " + fileOut.getPath());
}
KeyStore kspkcs12 = KeyStore.getInstance("PKCS12");
KeyStore ksjks = KeyStore.getInstance("jks");
char inphrase[] = certPassword.toCharArray();
char outphrase[] = certPassword.toCharArray();
kspkcs12.load(new FileInputStream(fileIn), inphrase);
ksjks.load(fileOut.exists() ? ((java.io.InputStream) (new FileInputStream(fileOut))) : null, outphrase);
Enumeration eAliases = kspkcs12.aliases();
do{
if(!eAliases.hasMoreElements())
break;
String strAlias = (String)eAliases.nextElement();
if(kspkcs12.isKeyEntry(strAlias))
{
java.security.Key key = kspkcs12.getKey(strAlias, inphrase);
Certificate chain[] = kspkcs12.getCertificateChain(strAlias);
ksjks.setKeyEntry(strAlias, key, outphrase, chain);
}
}
while(true);
OutputStream out = new FileOutputStream(fileOut);
ksjks.store(out, outphrase);
out.close();
}
catch(KeyStoreException e){
e.printStacktrace();
}
catch (NoSuchAlgorithmException e) {
e.printStacktrace();
}
catch (CertificateException e) {
e.printStacktrace();
}
catch (FileNotFoundException e) {
e.printStacktrace();
}
catch (IOException e) {
e.printStacktrace();
}
catch (UnrecoverableKeyException e) {
e.printStacktrace();
}
System.out.println("Java Key Store created successfully");
}
}
I Referred this link : Bouncycastle for JDK 1.7 and PKCS libraries – But well, it's not working for me.
The error is on this line : Signature signature = Signature.getInstance("SHA1WithRSA", "BC");
Best Answer
As mentioned here, Weblogic contains an invalid bcprov-jdk16-1.45.jar
Try to verify
MW_HOME/oracle_common/modules/bcprov-jdk16-1.45.jar
with jarsigner utility:The SecurityException is thrown:
The file differs from the one in the Maven Repository, that passes verification successfully.