title: CMS signature SHA1+RSA with PEM format - Java
body: <p>I need to generate a CMS with SHA1+RSA detached signature in PEM format over a xml file input. I need to make this from Java code in runtime. I need to avoid the use of an external tool like OpenSSL. This is because we need invoke some services with the generated signature from Java and manage error properly if an exception ocurred in the signature process (the input xml changes every day). </p>
  
  <p>The file I have to sign looks like this:</p>
  
  <pre><code>&lt;header&gt;    
   &lt;generationTime&gt;2017-04-17T00:00:01-03:00&lt;/generationTime&gt;
   &lt;expirationTime&gt;2017-04-17T23:59:59-03:00&lt;/expirationTime&gt;
  &lt;/header&gt;
  </code></pre>
  
  <p>Using OpenSSL, with a private key and a certificate, the signature is generated executing this command:</p>
  
  <pre><code>openssl cms -sign -in tra.xml -inkey MyPrivateKey -signer myCertificate.pem -out tra.xml.cms -outform PEM -nodetach
  </code></pre>
  
  <p>The generated PEM signature in that case is:</p>
  
  <pre><code>-----BEGIN CMS-----
  MIIGdAYJKoZIhvcNAQcCoIIGZTCCBmECAQExDTALBglghkgBZQMEAgEwgaIGCSqG
  SIb3DQEHAaCBlASBkTxoZWFkZXI+ICAgIA0KPGdlbmVyYXRpb25UaW1lPjIwMTct
  MDQtMTdUMDA6MDA6MDEtMDM6MDA8L2dlbmVyYXRpb25UaW1lPg0KPGV4cGlyYXRp
  b25UaW1lPjIwMTctMDQtMTdUMjM6NTk6NTktMDM6MDA8L2V4cGlyYXRpb25UaW1l
  Pg0KPC9oZWFkZXI+DQqgggNOMIIDSjCCAjKgAwIBAgIII0Or3JGYSY4wDQYJKoZI
  hvcNAQENBQAwODEaMBgGA1UEAwwRQ29tcHV0YWRvcmVzIFRlc3QxDTALBgNVBAoM
  BEFGSVAxCzAJBgNVBAYTAkFSMB4XDTE3MDEyNjE2MDIwNFoXDTE5MDEyNjE2MDIw
  NFowMDETMBEGA1UEAwwKYWNjZXNvQUZJUDEZMBcGA1UEBRMQQ1VJVCAyMDI5OTUw
  Mzk2OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPhtRXT8FQPvcFvQ
  CUSZaHTtcc864DsvP3zedpcr1gDLyJRMMlKnV0mZVJXEeC6eo6AV71kv2QpFUUp3
  OGUAS/zJGXByCJ2trV/pXrvppmJvAJARlfw6KoqQBY+YYoIinIzCbUHdvoPwub2K
  o7081VlmLxUffiDElbAi3gi41z/W6pD57i3U1uPjS45HRvIn7Vcv4epcH3x9+IDC
  DEbZ0hsKIiuJrH4RO1k50gSSaXjvAQSG8kbEXMQ89AxAeynI8jk964JpHc0qLj6y
  1sfvAyCSPq8ZFURribdboZi8G6oAccIM1pyMKA13+AcPkOFy0SyotjnFgrK2MMVZ
  +vEgNwECAwEAAaNgMF4wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSzstP//em6
  3t6NrxEhnNYgffJPbzAdBgNVHQ4EFgQUEuAlczdaDyI7hGuwyqR6ipLvTikwDgYD
  VR0PAQH/BAQDAgXgMA0GCSqGSIb3DQEBDQUAA4IBAQA+Pg0RQ7J5qiViZMk94tgD
  WAgTT0iIoVm65Xn2/czlBgefhxY6l4SKqQCONJpAMCUI2mEG6qgOg/u+GbN3pR+p
  1FSC2yDETRIpf9nekooTEot6A9r2Huykd4Sp3QHZEly9Sx3+3ek+w7Mg0k/+AtgT
  JodP0ArzCQyvBJCR8ZTTHjUazf2/9o0iEqQIKyp1vn2vv3JlMONBb7+ALqzCXgCb
  FVjFpF8PpZyWM/+J6WVrU19hB3wsdyhLh0M5CiBQ19aGC8R/0bWm2w2P3awOn8r4
  r/duYqdGzK/7zTpjtvk0VKax6/Pe5WIFLKXTP9LGpxbCQjxKpbVxMbzx1pDPGBjF
  MYICVDCCAlACAQEwRDA4MRowGAYDVQQDDBFDb21wdXRhZG9yZXMgVGVzdDENMAsG
  A1UECgwEQUZJUDELMAkGA1UEBhMCQVICCCNDq9yRmEmOMAsGCWCGSAFlAwQCAaCB
  5DAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNzA0
  MTcxMzM3MDVaMC8GCSqGSIb3DQEJBDEiBCBL5i3jl4+rfSfo/Pcu/CbI6JHGj0jg
  UGI/EucH7LBM6jB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQBKjALBglghkgB
  ZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDAN
  BggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkqhkiG9w0B
  AQEFAASCAQAMNHskWrhZCu/DmFQLCrAweTEacCwTJdYOx+704PS6DkflXQLpD9q4
  B0Psxx6gmN7HkHkrY4bD250TefZpKyD7IfJjdNQEz4SzgmtgMTl2a0JvlgpWSNjq
  au0WMkFXnoSo0oJ3s4FSHWAe15DlNFQn9HbKfjI/sIHpkhgA0u/Kr6ZHUSIEnfxS
  KVNxQ224uvFPGCggHnPIdtBRFgGn44J1hRyiYm0BLqJO5sAwV23gWB8OztsuBHqj
  imi4WWXnCVPk7/6BMGNuLpUH3bH6nfIPDfSL7bb7vXRhcQrjTU8o38/C3gDsJr2A
  4JNHkIjPMoo4l+wlS66MJQpOXadjYaFi
  -----END CMS-----
  </code></pre>
  
  <p>Thats is what I need generate over Java 7.</p>
  
  <p>I already read and make many test with Bouncy Castle and <code>java.security.cert</code> standard API, but I can't generate the same signature result. I checked internal representation from Bouncy Castle and the API is using DER format to hold the signature. And in the examples are always showing how to verify a signature, but no how to generate one and save it in a file or print it in PEM form.</p>
  
  <p>Here is an example of how I generate a BC signature, but the result is pretty different from what I need:</p>
  
  <pre><code>public static String encryptSHA1RSA(String xmlPayload) throws Exception {
    List             certList = new ArrayList();
    CMSTypedData     msg = new CMSProcessableByteArray(xmlPayload.getBytes());
    certList.add(CMSEncryptor.getSingCert());
    Store certs = new JcaCertStore(certList);
    CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
    ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(CMSEncryptor.getPrivateKey());
    gen.addSignerInfoGenerator( new JcaSignerInfoGeneratorBuilder(
      new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
      .build(sha1Signer, CMSEncryptor.getSingCert()));
  
    gen.addCertificates(certs);
    CMSSignedData sigData = gen.generate(msg, true);
  
    ASN1InputStream asn1 = new ASN1InputStream(sigData.getEncoded());
    FileOutputStream fos = new FileOutputStream(getSecurityFolderPath() + "/tra.test.cms");
    DEROutputStream dos = new DEROutputStream(fos);
    dos.writeObject(asn1.readObject());
  
    dos.flush();
    dos.close();
    asn1.close();
  
    return Base64Util.encodeBase64(new String(sigData.getEncoded()));
  }
  </code></pre>
  
  <p>Is different also if I  encode the result with base64:</p>
  
  <pre><code>return Base64Util.encodeBase64(new String(sigData.getEncoded()));
  </code></pre>
  
  <p>Any tips will be very apreciated</p>