From 11355f2b551b604b523c0e2f3fca20fdfc09c8d4 Mon Sep 17 00:00:00 2001 From: pppscn <35696959@qq.com> Date: Fri, 29 Mar 2024 10:59:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E5=8F=91=E9=80=81?= =?UTF-8?q?=E9=80=9A=E9=81=93`=E7=94=B5=E5=AD=90=E9=82=AE=E7=AE=B1`?= =?UTF-8?q?=E6=94=AF=E6=8C=81`S/MIME`=E6=88=96`OpenPGP`=E5=8A=A0=E5=AF=86?= =?UTF-8?q?=20#417?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sms/forwarder/utils/mail/PgpUtils.kt | 70 +++---------------- 1 file changed, 11 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/mail/PgpUtils.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/mail/PgpUtils.kt index 2d16580a..a595b16a 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/mail/PgpUtils.kt +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/mail/PgpUtils.kt @@ -80,7 +80,13 @@ class PgpUtils( Log.d(TAG, "sendSignedEmail") try { val originalMessage = getOriginalMessage() - val signedMessage = getSignedMessage(originalMessage) + val secretKeyDecryptor = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword(senderPGPSecretKeyPassword)) + val producerOptions = ProducerOptions.sign( + SigningOptions() + .addInlineSignature(secretKeyDecryptor, senderPGPSecretKeyRing!!, DocumentSignatureType.CANONICAL_TEXT_DOCUMENT) + .overrideHashAlgorithm(HashAlgorithm.SHA256) + ).setAsciiArmor(true) + val signedMessage = getEncryptedAndOrSignedMessage(originalMessage, producerOptions) Transport.send(signedMessage) Pair(true, "Email signed and sent successfully") } catch (e: Exception) { @@ -97,7 +103,7 @@ class PgpUtils( val producerOptions = ProducerOptions.encrypt( EncryptionOptions.encryptCommunications().addRecipient(recipientPGPPublicKeyRing!!) ).setAsciiArmor(true) - val encryptedMessage = getEncryptedMessage(originalMessage, producerOptions) + val encryptedMessage = getEncryptedAndOrSignedMessage(originalMessage, producerOptions) Transport.send(encryptedMessage) Pair(true, "Encrypted email sent successfully") } catch (e: Exception) { @@ -111,7 +117,6 @@ class PgpUtils( Log.d(TAG, "sendSignedAndEncryptedEmail") try { val originalMessage = getOriginalMessage() - val secretKeyDecryptor = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword(senderPGPSecretKeyPassword)) val producerOptions = ProducerOptions.signAndEncrypt( EncryptionOptions.encryptCommunications().addRecipient(recipientPGPPublicKeyRing!!), @@ -119,7 +124,7 @@ class PgpUtils( .addInlineSignature(secretKeyDecryptor, senderPGPSecretKeyRing!!, DocumentSignatureType.CANONICAL_TEXT_DOCUMENT) .overrideHashAlgorithm(HashAlgorithm.SHA256) ).setAsciiArmor(true) - val encryptedMessage = getEncryptedMessage(originalMessage, producerOptions) + val encryptedMessage = getEncryptedAndOrSignedMessage(originalMessage, producerOptions) Transport.send(encryptedMessage) Pair(true, "Signed and encrypted email sent successfully") } catch (e: Exception) { @@ -186,61 +191,8 @@ class PgpUtils( return message } - // 获取签名邮件: https://datatracker.ietf.org/doc/html/rfc3156#autoid-5 - private fun getSignedMessage(originalMessage: MimeMessage): MimeMessage { - // 将原始邮件作为第一个部分添加到 multipart 中 - val originalBodyPart = MimeBodyPart() - originalBodyPart.setContent(originalMessage.content, originalMessage.contentType) - - // 将原始消息写入InputStream - val baos = ByteArrayOutputStream() - originalBodyPart.writeTo(baos) - val inputStream: InputStream = ByteArrayInputStream(baos.toByteArray()) - - // 签名数据 - val secretKeyDecryptor = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword(senderPGPSecretKeyPassword)) - val outputStream = ByteArrayOutputStream() - val encryptionStream = PGPainless.encryptAndOrSign() - .onOutputStream(outputStream) - .withOptions( - ProducerOptions.sign( - SigningOptions() - .addDetachedSignature(secretKeyDecryptor, senderPGPSecretKeyRing!!, DocumentSignatureType.BINARY_DOCUMENT) - .overrideHashAlgorithm(HashAlgorithm.SHA256) - ).setAsciiArmor(true) - ) - Streams.pipeAll(inputStream, encryptionStream) - encryptionStream.close() - - // 签名部分 - val signaturePart = MimeBodyPart().apply { - //dataHandler = DataHandler(ByteArrayDataSource(outputStream.toString(), "application/pgp-signature")) - //fileName = "signature.asc" - setContent(outputStream.toString(), "application/pgp-signature") - //setHeader("Content-Type", "application/pgp-signature; name=\"signature.asc\"") - addHeader("Content-Description", "OpenPGP digital signature") - addHeader("Content-Disposition", "attachment; filename=\"signature.asc\"") - } - - val signedMultiPart = MimeMultipart("signed; micalg=pgp-sha256; protocol=\"application/pgp-signature\"") - signedMultiPart.addBodyPart(originalBodyPart, 0) - signedMultiPart.addBodyPart(signaturePart, 1) - - val signedMessage = MimeMessage(originalMessage.session) - signedMessage.setRecipients(Message.RecipientType.TO, originalMessage.getRecipients(Message.RecipientType.TO)) - signedMessage.setRecipients(Message.RecipientType.CC, originalMessage.getRecipients(Message.RecipientType.CC)) - signedMessage.setRecipients(Message.RecipientType.BCC, originalMessage.getRecipients(Message.RecipientType.BCC)) - signedMessage.addFrom(originalMessage.from) - signedMessage.subject = originalMessage.subject - signedMessage.sentDate = originalMessage.sentDate - signedMessage.setContent(signedMultiPart) - signedMessage.saveChanges() - - return signedMessage - } - - // 获取加密邮件: https://datatracker.ietf.org/doc/html/rfc3156#section-4 - private fun getEncryptedMessage(originalMessage: MimeMessage, producerOptions: ProducerOptions): MimeMessage { + // 获取加密或且签名邮件: https://datatracker.ietf.org/doc/html/rfc3156#section-4 + private fun getEncryptedAndOrSignedMessage(originalMessage: MimeMessage, producerOptions: ProducerOptions): MimeMessage { // 将原始消息写入InputStream val baos = ByteArrayOutputStream() originalMessage.writeTo(baos)