2014-07-14 203 views
3

我在使用java簽署電子郵件時遇到了一些問題。Java - 電子郵件簽名

我相信我的代碼很好,但是當我收到我的收件箱中的電子郵件時,它說它無法驗證簽名。

下面的代碼 - 很簡單:

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.superman.mail.smime.handlers.pkcs7_signature"); 
     mailcap.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.superman.mail.smime.handlers.pkcs7_mime"); 
     mailcap.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.superman.mail.smime.handlers.x_pkcs7_signature"); 
     mailcap.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.superman.mail.smime.handlers.x_pkcs7_mime"); 
     mailcap.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.superman.mail.smime.handlers.multipart_signed"); 

     CommandMap.setDefaultCommandMap(mailcap); 

     Security.addProvider(new BouncyCastleProvider()); 

     KeyStore keyStore = KeyStore.getInstance("JKS"); 

     InputStream ins = SigningEmail.class.getResourceAsStream("/keystore.jks"); 

     // Provide location of Java Keystore and password for access 
     keyStore.load(ins,"changeit".toCharArray()); 

     // Find the first legit alias in the keystore and use it 
     Enumeration<String> es = keyStore.aliases(); 
     String alias = ""; 
     while (es.hasMoreElements()) { 
      alias = es.nextElement(); 

      // Does alias refer to a private key? Assign true/false to isAlias & evaluate 
      if (isAlias = keyStore.isKeyEntry(alias)) { 
       break; 
      } 
     } 
     if (isAlias) { 
      KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, new KeyStore.PasswordProtection("***".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); 
      capabilities.addCapability(SMIMECapability.aES128_CBC); 
      capabilities.addCapability(SMIMECapability.aES192_CBC); 

      //Cert info 
      X500Name x500 = new X500Name(((X509Certificate) chain[0]).getIssuerDN().getName()); 
      IssuerAndSerialNumber serialNumber = new IssuerAndSerialNumber(x500 , ((X509Certificate) chain[0]).getSerialNumber()) ; 

      ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); 
      signedAttrs.add(new SMIMEEncryptionKeyPreferenceAttribute(serialNumber)); 
      signedAttrs.add(new SMIMECapabilitiesAttribute(capabilities)); 

      //Set X509 
      X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias); 
      List<X509Certificate> certList = new ArrayList<X509Certificate>(); 
      certList.add(cert); 
      Store certs = new JcaCertStore(certList); 


      //Signing generator 
      SMIMESignedGenerator gen = new SMIMESignedGenerator(); 
      gen.addSignerInfoGenerator(
         new JcaSimpleSignerInfoGeneratorBuilder() 
          .setProvider("BC") 
          .setSignedAttributeGenerator(new AttributeTable(signedAttrs)) 
          .build("SHA1withRSA", myPrivateKey, cert)); 
      gen.addCertificates(certs); 

      MimeMessage cloneOriginal = new MimeMessage(body); 

      //Sign 
      MimeMultipart mainPart = gen.generate(body , "BC"); 

      // Set the content of the signed message 
      cloneOriginal.setContent(mainPart, mainPart.getContentType()); 
      cloneOriginal.saveChanges(); 

      // Send the message 
      sender.send(cloneOriginal); 

這裏是我從郵件得到:

我使用.pfx生成與該命令的基石:

密鑰工具 - importkeystore -srckeystore /Users/sign.pfx -srcstoretype pkcs12 -destkeystore /Users/keystore.jks -deststoretype jks

它從權威和一切簽署。

因此,導入和代碼看起來不錯,我相信但它不工作,我想知道我缺少什麼。

謝謝!

回答

1

據我所知,GoDaddy不銷售電子郵件簽名證書。您可能想要閱讀this review by mozillathis以瞭解如何獲取。 This article解釋幾種類型的證書:

  1. Web服務器身份驗證證書
  2. 統一通信(UC)證書
  3. 通配符證書
  4. 擴展驗證證書
  5. 低保證/域驗證的證書
  6. 代碼簽名證書
  7. 電子郵件證書
  8. 根簽名證書

知道哪些SSL證書類型可以幫助您避免許多問題,如要使用的東西,它不是爲了做一個證書。

0

我不得不編輯提供程序來讓代碼運行,但後來它對我有用。謝謝!

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"); 
mailcap.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");