Replication of the OpenSSL command to sign a file in Java

I need to sign the file, and so far I have used the openssl , which works fine (the file is signed and verified).

 openssl smime -sign -in unsigned.mobileconfig -out signed.mobileconfig -signer myCrtFile.crt -inkey myKeyFile.key -certfile bundleCertificate.crt -outform der -nodetach 

But now I need to do this at runtime, so I need to sign the file programmatically. I am using BouncyCastle , but I am open to switch to another library.

I do not own certificates and even less BouncyCastle . This is what I came with.

Relevant files from the openssl command for the code below:

 myCrtFile.crt -> signerCertHolder myKeyFile.key -> privateKeyInfo bundleCertificate.crt -> certificateHolder 

 public byte[] sign(String message) throws IOException, CMSException, OperatorCreationException, CertificateEncodingException, MessagingException, CertificateException { Security.addProvider(new BouncyCastleProvider()); PrivateKeyInfo privateKeyInfo = loadInKey(); X509CertificateHolder signerCertHolder = loadSigner(); X509CertificateHolder certificateCertHolder = loadCertfile(); PrivateKey inKey = new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo); JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter(); X509Certificate signer = certificateConverter.getCertificate(signerCertHolder); X509Certificate certificate = certificateConverter.getCertificate(certificateCertHolder); List<X509Certificate> certificateList = new ArrayList(); certificateList.add(signer); certificateList.add(certificate); Store<?> certs = new JcaCertStore(certificateList); ContentSigner sha1signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(inKey); JcaSignerInfoGeneratorBuilder jcaSignerInfoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()); CMSSignedDataGenerator signGen = new CMSSignedDataGenerator(); signGen.addSignerInfoGenerator(jcaSignerInfoGeneratorBuilder.build(sha1signer, certificate)); signGen.addCertificates(certs); CMSTypedData content = new CMSProcessableByteArray(message.getBytes()); CMSSignedData signedData = signGen.generate(content, false); byte[] signeddata = signedData.getEncoded(); return signeddata; } 

Then I save byte[] to a file. When I open the file (this is the MDM mobileConfig file), it says: "The file is signed but cannot be verified." I feel like I'm close to a solution, but I don't know what I'm doing wrong.

Can someone help me figure out what I am missing to check the file?

PS; Certificates is the SSL certificate (GoDaddy), and bundleCertificate.crt is the certificate of the GoDaddy package.

0
source share
1 answer

I managed to sign the file. As expected, I was close to a final decision. Here is the full code.

 public byte[] signMobileConfig(byte[] mobileconfig) throws CertificateEncodingException, PEMException, FileNotFoundException, IOException, CertificateException, OperatorCreationException, CMSException { Security.addProvider(new BouncyCastleProvider()); X509CertificateHolder caCertificate = loadCertfile(); JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter(); X509Certificate serverCertificate = certificateConverter.getCertificate(loadSigner()); PrivateKeyInfo privateKeyInfo = loadInKey(); PrivateKey inKey = new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(inKey); CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); JcaDigestCalculatorProviderBuilder digestProviderBuilder = new JcaDigestCalculatorProviderBuilder().setProvider("BC"); JcaSignerInfoGeneratorBuilder generatotBuilder = new JcaSignerInfoGeneratorBuilder(digestProviderBuilder.build()); generator.addSignerInfoGenerator(generatotBuilder.build(sha1Signer, serverCertificate)); generator.addCertificate(new X509CertificateHolder(serverCertificate.getEncoded())); generator.addCertificate(new X509CertificateHolder(caCertificate.getEncoded())); CMSProcessableByteArray bytes = new CMSProcessableByteArray(mobileconfig); CMSSignedData signedData = generator.generate(bytes, true); return signedData.getEncoded(); } 

And this is how I upload files:

 public X509CertificateHolder loadSigner() throws FileNotFoundException, IOException { InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.crt"); PEMParser parser = new PEMParser(new InputStreamReader(inputStream)); return (X509CertificateHolder) parser.readObject(); } public PrivateKeyInfo loadInKey() throws FileNotFoundException, IOException { InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.key"); PEMParser parser = new PEMParser(new InputStreamReader(inputStream)); return (PrivateKeyInfo) parser.readObject(); } public X509CertificateHolder loadCertfile() throws FileNotFoundException, IOException { InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.crt"); PEMParser parser = new PEMParser(new InputStreamReader(inputStream)); return (X509CertificateHolder) parser.readObject(); } 
+1
source

Source: https://habr.com/ru/post/908431/


All Articles