Java: отправьте электронное письмо на адрес электронной почты, отличный от ASCII

Я хочу отправить электронное письмо на не-ASCII адрес электронной почты, и я не уверен, что это рекомендуемая процедура с использованием JDK8.

Как мне обращаться со следующими адресами электронной почты?

Есть ли какие-либо соображения безопасности, о которых нужно знать?

Будет ли этот примерный код достаточным?

import java.net.IDN;


public class IDNMailHelper {

    public static String toIdnAddress(String mail) {
        if (mail == null) {
            return null;
        }
        int idx = mail.indexOf('@');
        if (idx < 0) {
            return mail;
        }
        return localPart(mail, idx) + "@" + IDN.toASCII(domain(mail, idx));
    }

    private static String localPart(String mail, int idx) {
        return mail.substring(0, idx);
    }

    private static String domain(String mail, int idx) {
        return mail.substring(idx + 1);
    }

}

Ответы

Ответ 1

Paweł по сути прав, что адреса должны быть закодированы как UTF-8, если ваш сервер поддерживает это, но это сложнее, потому что в настоящее время JavaMail не поддерживает расширения сервера, которые позволяют использовать заголовки UTF-8.

Возможное обходное решение включает преобразование строки Java Unicode в кодированный байтовый массив UTF-8, а затем создание строки Java Unicode, где каждый байт является отдельным символом iso-8859-1. Я не пробовал это, поэтому я не знаю, столкнется ли он с другими проблемами, но без необходимой поддержки в JavaMail это, вероятно, ваша лучшая надежда.

Например:

address = new String(address.getBytes("utf-8"), "iso-8859-1");

Ответ 2

Из-за RFC6530 вы действительно должны закодировать электронное письмо как UTF-8. Это означает, что вы не должны использовать IDN здесь. Если ваши исходящие SMTP-серверы поддерживают EAI (интернационализированные электронные письма), это не должно быть проблемой.

Пожалуйста, имейте в виду, что EAI может представлять серьезную угрозу безопасности. Если вы решили обработать в своем приложении (услуге?), Не забудьте запретить пользователям регистрировать похожие адреса электронной почты, то есть те, которые используют разные сценарии. Например, один из этих ребят должен быть отклонен:

Ответ 3

Для заголовков вашей электронной почты это решение RFC-2047, которое определяет конкретный протокол кодирования для не-ISO- 646 символов в электронной почте. Java Mail имеет класс для использования этого: MimeUtility. Punicode/IDNS не подходит для использования заголовков.

Поскольку Билл Шеннон, еще один ответчик здесь, указал в этом ответе, Java Mail, в общем, автоматически применит MimeUtil к вашим заголовкам. Что касается вопроса в комментарии о промежуточных почтовых серверах, я отвечаю только на ваш вопрос о тексте в заголовках, который ни о чем не беспокоит. Что касается сообщений протокола SMTP, необходимых для фактического получения сообщения в нужном месте, я не утверждаю, что знаю.