Android=でメールクライアントアプリを構築しようとしていますが、今はjavaMail部分を構成したいと考えています。
私はimapサーバーとの接続を確立しようとしていますが、私のコードに何か問題があります。ここに私のコードがあります:
package mailpackage;
import Java.util.Properties;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
public class Connection implements Runnable
{
boolean done;
public Connection()
{
this.done=false;
}
@Override
public void run()
{
System.out.println("Hello from Connection Thread!");
while(!done)
{
String Host = "myhost";// change accordingly
String mailStoreType = "imap";
String username = "myusername";// change accordingly
String password = "mypasswd";// change accordingly
check(Host, mailStoreType, username, password);
}
}
public static void receiveEmail(String Host, String storeType, String username, String password)
{
try
{
Properties properties = new Properties();
properties.put("mail.imap.com", Host);
properties.put("mail.imap.starttls.enable","true");
properties.put("mail.imap.auth", "true"); // If you need to authenticate
// Use the following if you need SSL
properties.put("mail.imap.socketFactory.port", 993);
properties.put("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.put("mail.imap.socketFactory.fallback", "false");
Session emailSession = Session.getDefaultInstance(properties);
emailSession.setDebug(true);
//2) create the IMAP store object and connect with the Imap server
IMAPStore emailStore = (IMAPStore) emailSession.getStore(storeType);
emailStore.connect(Host, username, password);
//3) create the folder object and open it
Folder emailFolder = emailStore.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
//4) retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
for (int i = 0; i <messages.length; i++)
{
Message message = messages[i];
MimeMessage m = new MimeMessage(emailSession);
m.setContent(((MimeMessage)messages[i]).getContent() , "text/plain; charset=UTF-8");
System.out.println("---------------------------------");
System.out.println("Email Number " + (i + 1));
System.out.println("Subject: " + message.getSubject());
System.out.println("From: " + message.getFrom()[0]);
System.out.println("Text: " + message.getContent().toString());
m.writeTo(System.out);
}
//5) close the store and folder objects
emailFolder.close(false);
emailStore.close();
}
catch (NoSuchProviderException e) {e.printStackTrace();}
catch (MessagingException e) {e.printStackTrace();}
catch (IOException e) {e.printStackTrace();}
}
public void stopThread()
{
this.done=true;
}
}
このような別のクラスからスレッドを呼び出します
connec=new Connection();
(new Thread(connec)).start();
次のエラーが表示されます。
javax.mail.MessagingException: Sun.security.validator.ValidatorException: PKIX path building failed: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
nested exception is:
javax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: PKIX path building failed: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.Sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.Java:571)
at javax.mail.Service.connect(Service.Java:288)
at javax.mail.Service.connect(Service.Java:169)
at mailpackage.Connection.check(Connection.Java:63)
at mailpackage.Connection.run(Connection.Java:33)
at Java.lang.Thread.run(Thread.Java:744)
Caused by: javax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: PKIX path building failed: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at Sun.security.ssl.Alerts.getSSLException(Alerts.Java:192)
at Sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.Java:1884)
at Sun.security.ssl.Handshaker.fatalSE(Handshaker.Java:276)
at Sun.security.ssl.Handshaker.fatalSE(Handshaker.Java:270)
at Sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.Java:1341)
at Sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.Java:153)
at Sun.security.ssl.Handshaker.processLoop(Handshaker.Java:868)
at Sun.security.ssl.Handshaker.process_record(Handshaker.Java:804)
at Sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.Java:1016)
at Sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.Java:1312)
at Sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.Java:882)
at Sun.security.ssl.AppInputStream.read(AppInputStream.Java:102)
at com.Sun.mail.util.TraceInputStream.read(TraceInputStream.Java:110)
at Java.io.BufferedInputStream.fill(BufferedInputStream.Java:235)
at Java.io.BufferedInputStream.read(BufferedInputStream.Java:254)
at com.Sun.mail.iap.ResponseInputStream.readResponse(ResponseInputStream.Java:98)
at com.Sun.mail.iap.Response.<init>(Response.Java:96)
at com.Sun.mail.imap.protocol.IMAPResponse.<init>(IMAPResponse.Java:61)
at com.Sun.mail.imap.protocol.IMAPResponse.readResponse(IMAPResponse.Java:135)
at com.Sun.mail.imap.protocol.IMAPProtocol.readResponse(IMAPProtocol.Java:261)
at com.Sun.mail.iap.Protocol.<init>(Protocol.Java:114)
at com.Sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.Java:104)
at com.Sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.Java:538)
... 5 more
Caused by: Sun.security.validator.ValidatorException: PKIX path building failed: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at Sun.security.validator.PKIXValidator.doBuild(PKIXValidator.Java:385)
at Sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.Java:292)
at Sun.security.validator.Validator.validate(Validator.Java:260)
at Sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.Java:326)
at Sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.Java:231)
at Sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.Java:126)
at Sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.Java:1323)
... 23 more
Caused by: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at Sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.Java:196)
at Java.security.cert.CertPathBuilder.build(CertPathBuilder.Java:268)
at Sun.security.validator.PKIXValidator.doBuild(PKIXValidator.Java:380)
... 29 more
私は証明書をJava信頼できる証明書として保存それをするために。
//メールサーバーにアクセスできません
助言がありますか?ありがとう!
OK問題が解決しました!
解決策は次のとおりです。
まず、opensslを介してメールサーバーから自己署名証明書を取得します。
echo | openssl s_client -connect yoursever:port 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > yourcert.pem
次に、yourcert.pemファイルをこのパス/ Library/Java/Home/lib/security(macOSX上)に保存し、このようなcacertsに証明書ファイルを配置します
keytool -keystore cacerts -importcert -alias youralias -file yourcert.pem
デフォルトのキーストアパスワードはchangeitです
証明書のフィンガープリントを表示するこのコマンドで行った変更を表示できます。
keytool -list -keystore cacerts
この後、VMでこれらの引数を渡す必要があります
(WindowsおよびLinuxの場合、「」の間にyourpathを入力します)
-Djavax.net.ssl.trustStore="/Library/Java/Home/lib/security/cacerts"
-Djavax.net.ssl.trustStorePassword="changeit"
デバッグ用:
-Djava.security.debug=certpath
-Djavax.net.debug=trustmanager
ライブラリjavax.mail.jarを https://Java.net/projects/javamail/pages/Home (現在のバージョンは1.5.5)にアップグレードして、コードを追加できます。
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
properties.put("mail.imap.ssl.trust", "*");
properties.put("mail.imap.ssl.socketFactory", sf);
Java 7から証明書ファイルを取得することにより、この問題を解決する簡単な方法
次のJava 7ディレクトリから「cacerts」ファイルをコピーします
C:\Program Files\Java\jdk1.7.0_79\jre\lib\security
それをJava 6ディレクトリに貼り付けます
C:\Program Files\Java\jdk1.6.0\jre\lib\security
リンクされたサイトからの引用テキスト:
Q:SSL経由でメールサーバーに接続すると、「要求されたターゲットへの有効な証明書パスが見つかりません」などの例外が表示されます。
A:サーバーはおそらく、商用認証局によって署名された証明書ではなく、テスト証明書または自己署名証明書を使用しています。サーバーの証明書をトラストストアにインストールする必要があります。 InstallCertプログラムが役立ちます。
または、「mail.protocol.ssl.trust」プロパティをメールサーバーのホスト名に設定できます。詳細については、プロトコルプロバイダーパッケージのjavadocsを参照してください。
この問題の他の一般的な原因は次のとおりです。
- 要求を傍受するファイアウォールまたはウイルス対策プログラムがあります。
- JDKのインストールに問題があり、信頼できる認証局の証明書を見つけることができません。
- JDKの信頼できる認証局のリストをオーバーライドしたアプリケーションサーバーで実行しています。
また、メールサーバーと通信するときにこの問題に遭遇しました。ただし、根本的な原因は、サーバー(Exchange 2013)に実際の証明書と自己署名の両方が適用されていることです。適切な対応策は、サーバー上の自己署名を削除することでした。これは、自己署名が優先され、実際の証明書をブロックしていたためです。
私は交換する必要がありました:
props.setProperty("mail.smtp.starttls.enable", "true");
props.setProperty("mail.smtp.auth", "true");
で:
props.put("mail.smtp.starttls.enable", true);
props.put("mail.smtp.auth", true);
エラーを取り除きます。
古代のjavamailバージョンを含むjetty 9を使用していることに注意してください。
このエラーは、証明書に問題があることを意味する必要がないため、これを投稿しました。
解決策を探すのに何日も費やしましたが、この投稿は私にとって助けになりました。同じ問題がありました。次のようなpemファイルを作成した後、次のコマンドを使用して、certファイルの.pemをcacertファイル(TrustStore.jksというコピー)に追加しました。
keytool.exe -import -noprompt -keystore TrustStore.jks -storepass changeit ^ -alias DOMAINNAME -file MYCERTFILE.pem
(DOMAINNAMEはホスト名に置き換える必要があります-このトリックは非常に重要です-およびMYCERTFILEはファイルの最近の作成によって...)
このソリューションが誰かに役立つことを願っています。