Altering message body after signing does not invalidate signature

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Altering message body after signing does not invalidate signature

Jacob Richardson
In short, I sign email and then programatically alter the message body, and I feel that recipient should get a warning that message may have been altered, but does not. The steps I follow are below

1. Send email to mail proxy server with java mail client
2. Proxy server signs email
3. After signing I alter message body programatically
4. Proxy server forwards email to Exchange server
5. Exchange server delivers email to recipient

Recipient receives email at this point with a valid digital signature and no message that email has been altered. It seems to me the digest in the signed email and the digest that Exchange calculates should be different. Am i signing wrong? Is it possible Exchange is not comparing the digests?

The code I use to sign is below.


Thanks, JTR


PrivateKey myPrivateKey = pkEntry.getPrivateKey();

                // Load certificate chain
                Certificate[] chain = keyStore.getCertificateChain(alias);
                
                // Create the SMIMESignedGenerator
                SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
                capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
                capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
                capabilities.addCapability(SMIMECapability.dES_CBC);
                capabilities.addCapability(SMIMECapability.aES256_CBC);

                ASN1EncodableVector attributes = new ASN1EncodableVector();
                attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(
                        new IssuerAndSerialNumber(
                        new X500Name(((X509Certificate) chain[0])
                        .getIssuerDN().getName()),
                        ((X509Certificate) chain[0]).getSerialNumber())));
                attributes.add(new SMIMECapabilitiesAttribute(capabilities));

                SMIMESignedGenerator signer = new SMIMESignedGenerator();

                // Add the list of certs to the generator
                List<Certificate> certList = new ArrayList<Certificate>();
                certList.add(chain[0]);

                JcaCertStore certStore = new JcaCertStore(certList);
                signer.addCertificates(certStore);

                ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(myPrivateKey);
                signer.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
                        new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, (X509Certificate) chain[0]));

                // Sign the message
         logger.debug("Before Sign MimeMessage.");        

         MimeMultipart mm = signer.generate(m,new BouncyCastleProvider());
Reply | Threaded
Open this post in threaded view
|

RE: Altering message body after signing does not invalidate signature

Eckenfels. Bernd
What parts do the message have and what part did you modify. Looks like you modify a non-signed part.
--
http://www.seeburger.com
________________________________________
From: Jacob Richardson [[hidden email]]
Sent: Thursday, June 15, 2017 22:03
To: [hidden email]
Subject: [dev-crypto] Altering message body after signing does not invalidate signature

In short, I sign email and then programatically alter the message body, and I feel that recipient should get a warning that message may have been altered, but does not. The steps I follow are below

1. Send email to mail proxy server with java mail client
2. Proxy server signs email
3. After signing I alter message body programatically
4. Proxy server forwards email to Exchange server
5. Exchange server delivers email to recipient

Recipient receives email at this point with a valid digital signature and no message that email has been altered. It seems to me the digest in the signed email and the digest that Exchange calculates should be different. Am i signing wrong? Is it possible Exchange is not comparing the digests?

The code I use to sign is below.


Thanks, JTR


PrivateKey myPrivateKey = pkEntry.getPrivateKey();

                // Load certificate chain
                Certificate[] chain = keyStore.getCertificateChain(alias);

                // Create the SMIMESignedGenerator
                SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
                capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
                capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
                capabilities.addCapability(SMIMECapability.dES_CBC);
                capabilities.addCapability(SMIMECapability.aES256_CBC);

                ASN1EncodableVector attributes = new ASN1EncodableVector();
                attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(
                        new IssuerAndSerialNumber(
                        new X500Name(((X509Certificate) chain[0])
                        .getIssuerDN().getName()),
                        ((X509Certificate) chain[0]).getSerialNumber())));
                attributes.add(new SMIMECapabilitiesAttribute(capabilities));

                SMIMESignedGenerator signer = new SMIMESignedGenerator();

                // Add the list of certs to the generator
                List<Certificate> certList = new ArrayList<Certificate>();
                certList.add(chain[0]);

                JcaCertStore certStore = new JcaCertStore(certList);
                signer.addCertificates(certStore);

                ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(myPrivateKey);
                signer.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
                        new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, (X509Certificate) chain[0]));

                // Sign the message
         logger.debug("Before Sign MimeMessage.");

         MimeMultipart mm = signer.generate(m,new BouncyCastleProvider());








SEEBURGER AG            Vorstand/SEEBURGER Executive Board:
Sitz der Gesellschaft/Registered Office:                Axel Haas, Michael Kleeberg, Friedemann Heinz, Dr. Martin Kuntz, Matthias Feßenbecker
Edisonstr. 1
D-75015 Bretten         Vorsitzende des Aufsichtsrats/Chairperson of the SEEBURGER Supervisory Board:
Tel.: 07252 / 96 - 0            Prof. Dr. Simone Zeuchner
Fax: 07252 / 96 - 2222
Internet: http://www.seeburger.de               Registergericht/Commercial Register:
e-mail: [hidden email]               HRB 240708 Mannheim


Dieses E-Mail ist nur für den Empfänger bestimmt, an den es gerichtet ist und kann vertrauliches bzw. unter das Berufsgeheimnis fallendes Material enthalten. Jegliche darin enthaltene Ansicht oder Meinungsäußerung ist die des Autors und stellt nicht notwendigerweise die Ansicht oder Meinung der SEEBURGER AG dar. Sind Sie nicht der Empfänger, so haben Sie diese E-Mail irrtümlich erhalten und jegliche Verwendung, Veröffentlichung, Weiterleitung, Abschrift oder jeglicher Druck dieser E-Mail ist strengstens untersagt. Weder die SEEBURGER AG noch der Absender (Eckenfels. Bernd) übernehmen die Haftung für Viren; es obliegt Ihrer Verantwortung, die E-Mail und deren Anhänge auf Viren zu prüfen.


This email is intended only for the recipient(s) to whom it is addressed. This email may contain confidential material that may be protected by professional secrecy. Any fact or opinion contained, or expression of the material herein, does not necessarily reflect that of SEEBURGER AG. If you are not the addressee or if you have received this email in error, any use, publication or distribution including forwarding, copying or printing is strictly prohibited. Neither SEEBURGER AG, nor the sender (Eckenfels. Bernd) accept liability for viruses; it is your responsibility to check this email and its attachments for viruses.

Reply | Threaded
Open this post in threaded view
|

RE: Altering message body after signing does not invalidate signature

Jacob Richardson
In reply to this post by Jacob Richardson
Thanks for the reply. Here is where we change the text in body of email, but Exchange server indicates no change was made to signed email.



MimeMultipart mm = signer.generate(m,new BouncyCastleProvider());

                              mm.getBodyPart(0).setText("dsfasad");

      MimeMultipart mm = signer.generate(m,new BouncyCastleProvider());

                              mm.getBodyPart(0).setText("dsfasad");

[‎6/‎16/‎2017 10:11 AM] Cohen, Joshua S (US):


Note that we get body part zero because in bouncy castles code, the signed content comes before the signature itself



Thanks, JTR


 

Reply | Threaded
Open this post in threaded view
|

Re: Altering message body after signing does not invalidate signature

Jacob Richardson
In reply to this post by Eckenfels. Bernd
Hi, thanks for reply, complete code is below, I change body of email at end.   --Thanks, JTR

 
MimeMessage body = this.parseMessage(this.unsignedMailData);

MimeMultipart mp = new MimeMultipart();

           Object content = body.getContent();
           if (content instanceof Multipart) {
            logger.debug("Multipart message");
            handleMultipart(mp, (Multipart)content);
           } else {
            logger.debug("Not a Multipart message");
           MimeBodyPart singlePart = new MimeBodyPart();
           singlePart.setContent(body.getContent(),body.getContentType());
    mp.addBodyPart(singlePart);
            handlePart(body);
           }
           
           //Create the final MimeBodyPart that will be digitally signed
           MimeBodyPart m = new MimeBodyPart();
           m.setContent(mp);
                       
        boolean isAlias = false;
        // Add BouncyCastle content handlers to command map
           MailcapCommandMap mailcap = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
           mailcap.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature");
           mailcap.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");
           mailcap.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature");
           mailcap.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");
           mailcap.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");
           CommandMap.setDefaultCommandMap(mailcap);
           Security.addProvider(new BouncyCastleProvider());
           //Get an instance to a Java Key Store
           KeyStore keyStore;
keyStore = KeyStore.getInstance("JKS");
           // Provide location of Java Keystore and password for access
                ResourceBundle resource = ResourceBundle.getBundle("resources.mireka");  
                
                String xchar = resource.getString("xchar");
           String cne = resource.getString("cne");
                FileEncryptClass fec = new FileEncryptClass(EncryptionTypes.KEY_TYPE_DES,cne);
           
                fis = new FileInputStream(resource.getString("keystore.location"));
                
keyStore.load(fis, fec.decrypt(xchar).toCharArray());
           // Find the first legit alias in the keystore and use it
           Enumeration<String> es = keyStore.aliases();
           String alias = "";
           while (es.hasMoreElements()) {
               alias = (String) es.nextElement();
               
               // Does alias refer to a private key? Assign true/false to isAlias & evaluate
               if (isAlias = keyStore.isKeyEntry(alias)) {
                   break;
               }
           }
           
           if (isAlias) {
           
            //Get certificate private key
               KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, new KeyStore.PasswordProtection(xxxxxx.toCharArray()));
               PrivateKey myPrivateKey = pkEntry.getPrivateKey();

               // Load certificate chain
               Certificate[] chain = keyStore.getCertificateChain(alias);
               
               // Create the SMIMESignedGenerator
               SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
               capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
               capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
               capabilities.addCapability(SMIMECapability.dES_CBC);
               capabilities.addCapability(SMIMECapability.aES256_CBC);

               ASN1EncodableVector attributes = new ASN1EncodableVector();
               attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(
                       new IssuerAndSerialNumber(
                       new X500Name(((X509Certificate) chain[0])
                       .getIssuerDN().getName()),
                       ((X509Certificate) chain[0]).getSerialNumber())));
               attributes.add(new SMIMECapabilitiesAttribute(capabilities));

               SMIMESignedGenerator signer = new SMIMESignedGenerator();

               // Add the list of certs to the generator
               List<Certificate> certList = new ArrayList<Certificate>();
               certList.add(chain[0]);

               JcaCertStore certStore = new JcaCertStore(certList);
               signer.addCertificates(certStore);

               ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(myPrivateKey);
               signer.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
                       new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, (X509Certificate) chain[0]));

               // Sign the message
        logger.debug("Before Sign MimeMessage.");        

        MimeMultipart mm = signer.generate(m,new BouncyCastleProvider());

        logger.debug("After Sign MimeMessage."); 
//**Body of email changed here!!!!
mm.getBodyPart(0).setText("dsfasad"); 
//**Email then forwarded to Exchange server, but Exchange does not detect the change      
               
              


On Thu, Jun 15, 2017 at 8:04 PM, Eckenfels. Bernd <[hidden email]> wrote:
What parts do the message have and what part did you modify. Looks like you modify a non-signed part.
--
http://www.seeburger.com
________________________________________
From: Jacob Richardson [[hidden email]]
Sent: Thursday, June 15, 2017 22:03
To: [hidden email]
Subject: [dev-crypto] Altering message body after signing does not invalidate signature

In short, I sign email and then programatically alter the message body, and I feel that recipient should get a warning that message may have been altered, but does not. The steps I follow are below

1. Send email to mail proxy server with java mail client
2. Proxy server signs email
3. After signing I alter message body programatically
4. Proxy server forwards email to Exchange server
5. Exchange server delivers email to recipient

Recipient receives email at this point with a valid digital signature and no message that email has been altered. It seems to me the digest in the signed email and the digest that Exchange calculates should be different. Am i signing wrong? Is it possible Exchange is not comparing the digests?

The code I use to sign is below.


Thanks, JTR


PrivateKey myPrivateKey = pkEntry.getPrivateKey();

                // Load certificate chain
                Certificate[] chain = keyStore.getCertificateChain(alias);

                // Create the SMIMESignedGenerator
                SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
                capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
                capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
                capabilities.addCapability(SMIMECapability.dES_CBC);
                capabilities.addCapability(SMIMECapability.aES256_CBC);

                ASN1EncodableVector attributes = new ASN1EncodableVector();
                attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(
                        new IssuerAndSerialNumber(
                        new X500Name(((X509Certificate) chain[0])
                        .getIssuerDN().getName()),
                        ((X509Certificate) chain[0]).getSerialNumber())));
                attributes.add(new SMIMECapabilitiesAttribute(capabilities));

                SMIMESignedGenerator signer = new SMIMESignedGenerator();

                // Add the list of certs to the generator
                List<Certificate> certList = new ArrayList<Certificate>();
                certList.add(chain[0]);

                JcaCertStore certStore = new JcaCertStore(certList);
                signer.addCertificates(certStore);

                ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(myPrivateKey);
                signer.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
                        new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, (X509Certificate) chain[0]));

                // Sign the message
         logger.debug("Before Sign MimeMessage.");

         MimeMultipart mm = signer.generate(m,new BouncyCastleProvider());








SEEBURGER AG            Vorstand/SEEBURGER Executive Board:
Sitz der Gesellschaft/Registered Office:                Axel Haas, Michael Kleeberg, Friedemann Heinz, Dr. Martin Kuntz, Matthias Feßenbecker
Edisonstr. 1
D-75015 Bretten         Vorsitzende des Aufsichtsrats/Chairperson of the SEEBURGER Supervisory Board:
Tel.: 07252 / 96 - 0            Prof. Dr. Simone Zeuchner
Fax: 07252 / 96 - 2222
Internet: http://www.seeburger.de               Registergericht/Commercial Register:
e-mail: [hidden email]               HRB 240708 Mannheim


Dieses E-Mail ist nur für den Empfänger bestimmt, an den es gerichtet ist und kann vertrauliches bzw. unter das Berufsgeheimnis fallendes Material enthalten. Jegliche darin enthaltene Ansicht oder Meinungsäußerung ist die des Autors und stellt nicht notwendigerweise die Ansicht oder Meinung der SEEBURGER AG dar. Sind Sie nicht der Empfänger, so haben Sie diese E-Mail irrtümlich erhalten und jegliche Verwendung, Veröffentlichung, Weiterleitung, Abschrift oder jeglicher Druck dieser E-Mail ist strengstens untersagt. Weder die SEEBURGER AG noch der Absender (Eckenfels. Bernd) übernehmen die Haftung für Viren; es obliegt Ihrer Verantwortung, die E-Mail und deren Anhänge auf Viren zu prüfen.


This email is intended only for the recipient(s) to whom it is addressed. This email may contain confidential material that may be protected by professional secrecy. Any fact or opinion contained, or expression of the material herein, does not necessarily reflect that of SEEBURGER AG. If you are not the addressee or if you have received this email in error, any use, publication or distribution including forwarding, copying or printing is strictly prohibited. Neither SEEBURGER AG, nor the sender (Eckenfels. Bernd) accept liability for viruses; it is your responsibility to check this email and its attachments for viruses.


Reply | Threaded
Open this post in threaded view
|

Re: Altering message body after signing does not invalidate signature

martijn.list
See my comments inline:

On 06/16/2017 09:55 PM, Jacob Richardson wrote:

> Hi, thanks for reply, complete code is below, I change body of email at
> end.   --Thanks, JTR
>
>  
> MimeMessage body = this.parseMessage(this.unsignedMailData);
>
> MimeMultipart mp = new MimeMultipart();
>
>            Object content = body.getContent();
>            if (content instanceof Multipart) {
>            logger.debug("Multipart message");
>            handleMultipart(mp, (Multipart)content);
>            } else {
>            logger.debug("Not a Multipart message");
>            MimeBodyPart singlePart = new MimeBodyPart();
>            singlePart.setContent(body.getContent(),body.getContentType());
>    mp.addBodyPart(singlePart);
>            handlePart(body);
>            }
>            
>            //Create the final MimeBodyPart that will be digitally signed
>            MimeBodyPart m = new MimeBodyPart();
>            m.setContent(mp);
>                      
>        boolean isAlias = false;
>        // Add BouncyCastle content handlers to command map
>            MailcapCommandMap mailcap = (MailcapCommandMap)
> CommandMap.getDefaultCommandMap();
>            mailcap.addMailcap("application/pkcs7-signature;;
> x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature");
>            mailcap.addMailcap("application/pkcs7-mime;;
> x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");
>            mailcap.addMailcap("application/x-pkcs7-signature;;
> x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature");
>            mailcap.addMailcap("application/x-pkcs7-mime;;
> x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");
>            mailcap.addMailcap("multipart/signed;;
> x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");
>            CommandMap.setDefaultCommandMap(mailcap);
>            Security.addProvider(new BouncyCastleProvider());
>            //Get an instance to a Java Key Store
>            KeyStore keyStore;
> keyStore = KeyStore.getInstance("JKS");
>            // Provide location of Java Keystore and password for access
>                 ResourceBundle resource =
> ResourceBundle.getBundle("resources.mireka");  
>                
>                 String xchar = resource.getString("xchar");
>           String cne = resource.getString("cne");
>                 FileEncryptClass fec = new
> FileEncryptClass(EncryptionTypes.KEY_TYPE_DES,cne);
>          
>                 fis = new
> FileInputStream(resource.getString("keystore.location"));
>                
> keyStore.load(fis, fec.decrypt(xchar).toCharArray());
>            // Find the first legit alias in the keystore and use it
>            Enumeration<String> es = keyStore.aliases();
>            String alias = "";
>            while (es.hasMoreElements()) {
>                alias = (String) es.nextElement();
>                
>                // Does alias refer to a private key? Assign true/false
> to isAlias & evaluate
>                if (isAlias = keyStore.isKeyEntry(alias)) {
>                    break;
>                }
>            }
>            
>            if (isAlias) {
>            
>            //Get certificate private key
>                KeyStore.PrivateKeyEntry pkEntry =
> (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, new
> KeyStore.PasswordProtection(xxxxxx.toCharArray()));
>                PrivateKey myPrivateKey = pkEntry.getPrivateKey();
>
>                // Load certificate chain
>                Certificate[] chain = keyStore.getCertificateChain(alias);
>                
>                // Create the SMIMESignedGenerator
>                SMIMECapabilityVector capabilities = new
> SMIMECapabilityVector();
>                capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
>                capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
>                capabilities.addCapability(SMIMECapability.dES_CBC);
>                capabilities.addCapability(SMIMECapability.aES256_CBC);
>
>                ASN1EncodableVector attributes = new ASN1EncodableVector();
>                attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(
>                        new IssuerAndSerialNumber(
>                        new X500Name(((X509Certificate) chain[0])
>                        .getIssuerDN().getName()),
>                        ((X509Certificate) chain[0]).getSerialNumber())));
>                attributes.add(new SMIMECapabilitiesAttribute(capabilities));
>
>                SMIMESignedGenerator signer = new SMIMESignedGenerator();
>
>                // Add the list of certs to the generator
>                List<Certificate> certList = new ArrayList<Certificate>();
>                certList.add(chain[0]);
>
>                JcaCertStore certStore = new JcaCertStore(certList);
>                signer.addCertificates(certStore);
>
>                ContentSigner sha1Signer = new
> JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(myPrivateKey);
>                signer.addSignerInfoGenerator(new
> JcaSignerInfoGeneratorBuilder(
>                        new
> JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer,
> (X509Certificate) chain[0]));
>
>                // Sign the message
>        logger.debug("Before Sign MimeMessage.");        
>
>        MimeMultipart mm = signer.generate(m,new BouncyCastleProvider());
>
>        logger.debug("After Sign MimeMessage.");
> //**Body of email changed here!!!!
> mm.getBodyPart(0).setText("dsfasad");
> //**Email then forwarded to Exchange server, but Exchange does not
> detect the change      

Afaik, BC will generate the signature when the message is written to
MIME (using MimeMessage#writeTo) so if you change the body text before
calling MimeMessage#writeTo, the changed part will be signed when
writing the message. You can check this by writing the message to MIME
(using MimeMessage#writeTo), then create a MimeMessage from the signed
message and then alter the body.

Kind regards,

Martijn Brinkers

--
CipherMail email encryption

Email encryption with support for S/MIME, OpenPGP, PDF encryption and
secure webmail pull.

https://www.ciphermail.com

Twitter: http://twitter.com/CipherMail


> On Thu, Jun 15, 2017 at 8:04 PM, Eckenfels. Bernd
> <[hidden email] <mailto:[hidden email]>> wrote:
>
>     What parts do the message have and what part did you modify. Looks
>     like you modify a non-signed part.
>     --
>     http://www.seeburger.com
>     ________________________________________
>     From: Jacob Richardson [[hidden email]
>     <mailto:[hidden email]>]
>     Sent: Thursday, June 15, 2017 22:03
>     To: [hidden email] <mailto:[hidden email]>
>     Subject: [dev-crypto] Altering message body after signing does not
>     invalidate signature
>
>     In short, I sign email and then programatically alter the message
>     body, and I feel that recipient should get a warning that message
>     may have been altered, but does not. The steps I follow are below
>
>     1. Send email to mail proxy server with java mail client
>     2. Proxy server signs email
>     3. After signing I alter message body programatically
>     4. Proxy server forwards email to Exchange server
>     5. Exchange server delivers email to recipient
>
>     Recipient receives email at this point with a valid digital
>     signature and no message that email has been altered. It seems to me
>     the digest in the signed email and the digest that Exchange
>     calculates should be different. Am i signing wrong? Is it possible
>     Exchange is not comparing the digests?
>
>     The code I use to sign is below.
>
>
>     Thanks, JTR
>
>
>     PrivateKey myPrivateKey = pkEntry.getPrivateKey();
>
>                     // Load certificate chain
>                     Certificate[] chain =
>     keyStore.getCertificateChain(alias);
>
>                     // Create the SMIMESignedGenerator
>                     SMIMECapabilityVector capabilities = new
>     SMIMECapabilityVector();
>                    
>     capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
>                     capabilities.addCapability(SMIMECapability.rC2_CBC,
>     128);
>                     capabilities.addCapability(SMIMECapability.dES_CBC);
>                     capabilities.addCapability(SMIMECapability.aES256_CBC);
>
>                     ASN1EncodableVector attributes = new
>     ASN1EncodableVector();
>                     attributes.add(new
>     SMIMEEncryptionKeyPreferenceAttribute(
>                             new IssuerAndSerialNumber(
>                             new X500Name(((X509Certificate) chain[0])
>                             .getIssuerDN().getName()),
>                             ((X509Certificate)
>     chain[0]).getSerialNumber())));
>                     attributes.add(new
>     SMIMECapabilitiesAttribute(capabilities));
>
>                     SMIMESignedGenerator signer = new
>     SMIMESignedGenerator();
>
>                     // Add the list of certs to the generator
>                     List<Certificate> certList = new
>     ArrayList<Certificate>();
>                     certList.add(chain[0]);
>
>                     JcaCertStore certStore = new JcaCertStore(certList);
>                     signer.addCertificates(certStore);
>
>                     ContentSigner sha1Signer = new
>     JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(myPrivateKey);
>                     signer.addSignerInfoGenerator(new
>     JcaSignerInfoGeneratorBuilder(
>                             new
>     JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer,
>     (X509Certificate) chain[0]));
>
>                     // Sign the message
>              logger.debug("Before Sign MimeMessage.");
>
>              MimeMultipart mm = signer.generate(m,new
>     BouncyCastleProvider());
>
>
>
>
>
>
>
>
>     SEEBURGER AG            Vorstand/SEEBURGER Executive Board:
>     Sitz der Gesellschaft/Registered Office:                Axel Haas,
>     Michael Kleeberg, Friedemann Heinz, Dr. Martin Kuntz, Matthias
>     Feßenbecker
>     Edisonstr. 1
>     D-75015 Bretten         Vorsitzende des Aufsichtsrats/Chairperson of
>     the SEEBURGER Supervisory Board:
>     Tel.: 07252 / 96 - 0            Prof. Dr. Simone Zeuchner
>     Fax: 07252 / 96 - 2222
>     Internet: http://www.seeburger.de             
>      Registergericht/Commercial Register:
>     e-mail: [hidden email] <mailto:[hidden email]>            
>      HRB 240708 Mannheim
>
>
>     Dieses E-Mail ist nur für den Empfänger bestimmt, an den es
>     gerichtet ist und kann vertrauliches bzw. unter das Berufsgeheimnis
>     fallendes Material enthalten. Jegliche darin enthaltene Ansicht oder
>     Meinungsäußerung ist die des Autors und stellt nicht
>     notwendigerweise die Ansicht oder Meinung der SEEBURGER AG dar. Sind
>     Sie nicht der Empfänger, so haben Sie diese E-Mail irrtümlich
>     erhalten und jegliche Verwendung, Veröffentlichung, Weiterleitung,
>     Abschrift oder jeglicher Druck dieser E-Mail ist strengstens
>     untersagt. Weder die SEEBURGER AG noch der Absender (Eckenfels.
>     Bernd) übernehmen die Haftung für Viren; es obliegt Ihrer
>     Verantwortung, die E-Mail und deren Anhänge auf Viren zu prüfen.
>
>
>     This email is intended only for the recipient(s) to whom it is
>     addressed. This email may contain confidential material that may be
>     protected by professional secrecy. Any fact or opinion contained, or
>     expression of the material herein, does not necessarily reflect that
>     of SEEBURGER AG. If you are not the addressee or if you have
>     received this email in error, any use, publication or distribution
>     including forwarding, copying or printing is strictly prohibited.
>     Neither SEEBURGER AG, nor the sender (Eckenfels. Bernd) accept
>     liability for viruses; it is your responsibility to check this email
>     and its attachments for viruses.
>
>