2016-11-10 49 views
0

我正嘗試使用JavaMAIL API發送數字簽名/刻錄郵件。是否可以使用發件人的憑據發送安全郵件?

爲此,我創建了KEYSTORE證書,並在生成此郵件並將其發送給用戶時使用(通過bouncycastle加載)。但是我必須提供發件人郵件ID的用戶名和密碼才能進行驗證。

是否有任何方式發送安全的郵件與發件人的憑據?

我嘗試通過認證爲false。但沒有運氣。

props.put("mail.smtp.auth", "true"); //enable authentication 

我的代碼:::

public static void main(String[] args) { 
    final String fromEmail = "[email protected]"; //requires valid gmail id 
    final String toEmail = "[email protected]"; 



    System.out.println("TLSEmail Start"); 
    Properties props = new Properties(); 

    props.put("mail.transport.protocol", "smtp"); 
    props.put("mail.smtp.host", "132.000.000.001"); //SMTP Host 
    props.put("mail.smtp.port", "587"); //TLS Port 
    props.put("mail.smtp.auth", "true"); //enable authentication 
    props.put("mail.smtp.starttls.enable", "true"); //enable STARTTLS 

    props.put("mail.smtp.ssl.trust", "*"); 
    props.put("mail.debug", "true"); 

    Session session = Session.getDefaultInstance(props, 
       new javax.mail.Authenticator() { 
        protected PasswordAuthentication getPasswordAuthentication() { 
         return new PasswordAuthentication("MYUSERNAME","MYPASSWORD"); 
        } 
       }); 

    boolean isAlias = false; 


    //Session session = Session.getDefaultInstance(props); 

    System.out.println("SESSION CREATED.............."); 

      try { 

       // Add BouncyCastle content handlers to command map 
       MailcapCommandMap mailcap = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); 
       mailcap.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed"); 
       CommandMap.setDefaultCommandMap(mailcap); 

       Security.addProvider(new BouncyCastleProvider()); 

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

       // Provide location of Java Keystore and password for access 
       keyStore.load(new FileInputStream("D:\\CERTIFICATES\\MAIL_CERT\\selfservice.cert"), 
         "keystore".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) { 
        KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, new KeyStore.PasswordProtection("keystore".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(); 
        signer.addSigner(
          myPrivateKey, 
          (X509Certificate) chain[0], 
          "DSA".equals(myPrivateKey.getAlgorithm()) ? SMIMESignedGenerator.DIGEST_SHA1 
          : SMIMESignedGenerator.DIGEST_MD5, 
          new AttributeTable(attributes), null); 

        // Add the list of certs to the generator 
        List certList = new ArrayList(); 
        certList.add(chain[0]); 
        CertStore certs = CertStore.getInstance("Collection", 
          new CollectionCertStoreParameters(certList), "BC"); 
        signer.addCertificatesAndCRLs(certs); 

        // Construct the message body 
        MimeMessage body = new MimeMessage(session); 
        body.setFrom(new InternetAddress(fromEmail)); 
        body.setRecipient(Message.RecipientType.TO, new InternetAddress(toEmail)); 
        body.setContent("DEAR.....BODY....", "text/plain"); 
        body.saveChanges(); 


        // Sign the message 
        MimeMultipart mm = signer.generate(body, "BC"); 
        MimeMessage signedMessage = new MimeMessage(session); 

        signedMessage.setFrom(new InternetAddress(fromEmail)); 
        signedMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(toEmail)); 
        signedMessage.setSubject("Testing Signed Subject"); 
        // Set the content of the signed message 
        signedMessage.setContent(mm); 
        signedMessage.saveChanges(); 

        // Send the message 
        Transport.send(signedMessage); 
       } 

      } catch (MessagingException e) { 
       throw new RuntimeException(e); 
      } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException | UnrecoverableEntryException | 
        InvalidAlgorithmParameterException | NoSuchProviderException | CertStoreException |SMIMEException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

} 
+0

你面臨什麼錯誤?發送電子郵件顯然不取決於您的任何憑據(對於SMTP身份驗證),並且加密僅需要接收者公鑰(這是hmm ** public **。)。 – Jan

回答

0

簽名或加密電子郵件的創作是完全獨立的登錄到郵件服務器和發送電子郵件的能力。沒有公共電子郵件服務器會讓你在沒有登錄的情況下發送電子郵件。如果您有用戶的私鑰來創建簽名的電子郵件,則您還需要用戶的密碼才能登錄到郵件服務器。

相關問題