Wie unterschreibe ich eine E-Mail mit PGP/MIME in Java?Java

Java-Forum
Anonymous
 Wie unterschreibe ich eine E-Mail mit PGP/MIME in Java?

Post by Anonymous »

In meinem Java-Programm möchte ich E-Mails senden, die mit einem OpenPGP-Schlüssel im PGP/MIME-Format signiert sind, wie in RFC 3156 definiert. Dafür verwende ich PGPainless-SOP- und Angus-Mails. Die Unterzeichnung des Inhalts einer E-Mail funktioniert jedoch noch nicht, da Thunderbird immer sagt, dass „es eine Signatur gibt, aber ungültig ist“. Ich vermute, dass der Inhalt der E-Mail noch nicht gemäß RFC 3156 formatiert ist, aber ich habe keine Ahnung, was das spezifische Problem ist. Whitespace
[*] Ersetzen von Zeilenenden durch CRLF
Der angegebene Hashing-Algorithmus: pgp-sha256 vs. pgp-sha512 (ich habe keine Ahnung, welche pgpains verwendet. Abgelehnt die Signatur.

Code: Select all

@Test
public void testSendSignedMessage() throws MessagingException, IOException {
String SECRET_KEY = "...";
String PASSWORD = "...";

Properties properties = new Properties();
properties.put("mail.smtp.auth", true);
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.smtp.host", "smtp.cia.gov");
properties.put("mail.smtp.port", "465");

properties.put("mail.store.protocol", "imaps");
properties.put("mail.imap.host", "imap.cia.gov");
properties.put("mail.imap.port", "993");
properties.put("mail.imap.ssl.enable", "true");

Session session = Session.getInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("jason.bourne@cia.gov", "treadstone");
}
});

MimeMessage email = new MimeMessage(session);

email.setFrom("jason.bourne@cia.gov");
email.setRecipient(Message.RecipientType.TO, new InternetAddress("pamela.landy@cia.gov"));
email.setSubject("Get some rest");

MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("You look tired.");

MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(textPart);

email.setContent(multipart);
this.signMessage(email, SECRET_KEY, PASSWORD.getBytes(), session);
Transport.send(email);
}

private void signMessage(MimeMessage email, byte[] secretKey, byte[] password, Session session)
throws MessagingException, IOException
{
Multipart signedMultipart = new MimeMultipart();
MimeBodyPart contentBody = new MimeBodyPart();
MimeBodyPart signatureBody = new MimeBodyPart();

Multipart contentMultipart = (Multipart) email.getContent();
contentBody.setContent(contentMultipart);
signedMultipart.addBodyPart(contentBody);

Part temporaryEmail = new MimeMessage(session);
temporaryEmail.setContent(contentMultipart);

OutputStream outputStream = new ByteArrayOutputStream();
temporaryEmail.writeTo(outputStream);
String boundary = this.parseBoundary(String.valueOf(outputStream)).orElse("");

signatureBody.attachFile(this.createSignatureAttachment(contentMultipart, secretKey, password, boundary));
signatureBody.setHeader("Content-Type", "application/pgp-signature; name=\"signature.asc\"");
signatureBody.setHeader("Content-Description", "OpenPGP signature");
signatureBody.setHeader("Content-Disposition", "attachment; filename=\"signature.asc\"");

signedMultipart.addBodyPart(signatureBody);
email.setContent(signedMultipart);

outputStream = new ByteArrayOutputStream();
email.writeTo(outputStream);
boundary = parseBoundary(String.valueOf(outputStream)).orElse("");

email.setHeader(
"Content-Type",
"multipart/signed; micalg=\"pgp-sha256\"; protocol=\"application/pgp-signature\"%s".formatted(
boundary.isEmpty() ? "" : ";  boundary=\"%s\"".formatted(boundary)
)
);
}

private File createSignatureAttachment(
Multipart message,
byte[] secretKey,
byte[] password,
String boundary
) throws IOException, MessagingException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
message.writeTo(outputStream);

String messageContent =
outputStream
.toString(StandardCharsets.UTF_8)
.replaceFirst("^-*%s-*".formatted(boundary), "") // Remove the leading boundary
.replaceFirst("-*%s-*$".formatted(boundary), "") // Remove the trailing boundary
.replaceFirst("^[\n\r]+", "") // Remove leading newlines
.replaceFirst("[\n\r\\s]+$", "") // Remove trailing newlines and whitespace
.replaceAll("(?.+)\"", Pattern.CASE_INSENSITIVE)
.matcher(contentTypeHeader);

if (matcher.find())
return Optional.of(matcher.group("boundary"));

return Optional.empty();
}
< /code>
Die relevanten Abhängigkeiten: < /p>

jakarta.mail
jakarta.mail-api
${jakarta-mail.version}


org.eclipse.angus
angus-mail
${angus-mail.version}


org.pgpainless
pgpainless-sop
${pgpainless.version}

< /code>
Der Körper der resultierenden E-Mail sieht folgendermaßen aus: < /p>
------=_Part_1_166454155.1747153500629
Content-Type: multipart/mixed;
boundary="----=_Part_0_1604052588.1747153500624"

------=_Part_0_1604052588.1747153500624
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

You look tired.
------=_Part_0_1604052588.1747153500624--

------=_Part_1_166454155.1747153500629
Content-Type: application/pgp-signature; name="signature.asc"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="signature.asc"
Content-Description: OpenPGP signature

-----BEGIN PGP SIGNATURE-----

iHUEABYKACcFg...
-----END PGP SIGNATURE-----

------=_Part_1_166454155.1747153500629--
Was habe ich falsch gemacht?>

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post