Android Intent使用p7s数字签名来签署电子邮件

时间:2014-07-18 11:58:53

标签: android email android-intent digital-signature email-attachments

我正在尝试发送一个由用户选择的电子邮件应用处理的Intent。 Intent有一个签名作为附件。我读到Gmail应用无法处理自定义mime类型,因此我点击K-9 Mail来处理意图。

Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"foo@bar.com"});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email test");
emailIntent.putExtra(Intent.EXTRA_TEXT, confirmEmailBody);
emailIntent.putExtra(Intent.EXTRA_STREAM, uriSigned);
emailIntent.setType("application/pkcs7-signature");
try {
    startActivity(Intent.createChooser(emailIntent, "Sending email..."));
} catch (android.content.ActivityNotFoundException ex) {
    Toast.makeText(this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}

我已经从字符串confirmEmailBody生成的p7s文件(存在于SD卡上)中签名。上面的意图设置了附件属性,如下所示:

Content-Transfer-Encoding: base64
Content-Type: application/pkcs7-signature;
 name="smime.p7s"
Content-Disposition: attachment;
 filename="smime.p7s";
 size=1886

但是,附件未被发现作为签名,因为一般电子邮件内容类型(位于发件人信息,时间等旁边)是多部分/混合的,应该是多部分/签名。 如何在intent中设置标题,以便最终在电子邮件中以 Content-Type:multipart / signed; 结束?

在它显示为签名后,我将查看是否会对电子邮件正文进行验证。

P.S。当然,我可以使用javamail轻松发送正确签名的电子邮件,但我想避免向用户询问手机的Gmail密码。

1 个答案:

答案 0 :(得分:1)

由于我没有找到方法以我想要的方式完成这项工作,我想我会发布另一种方法来解决问题,仍然避免要求输入密码。我使用Google Play服务获取Auth2令牌。

String token = GoogleAuthUtil.getToken(context, userEmail, "oauth2:https://mail.google.com/");
SMTPTransport smtpTransport = connectToSmtp("smtp.gmail.com", 587, userEmail, token, true);

SMTPMessage smtpMessage = new SMTPMessage(smtpSession);
smtpMessage.setFrom(new InternetAddress(userEmail));
smtpMessage.addRecipient(Message.RecipientType.TO, toAddress);
smtpMessage.setSubject(subject);
smtpMessage.setContent(multipart, multipart.getContentType());
smtpMessage.saveChanges();

smtpTransport.sendMessage(smtpMessage, smtpMessage.getAllRecipients());
smtpTransport.close();

当然,您可以选择适合您需求的oauth2范围。设置SMTPTransport以接受令牌(并为上面的代码创建smtpSession):

private SMTPTransport connectToSmtp(String host, int port, String userEmail, String oauthToken, boolean debug) throws Exception {
        Properties props = new Properties();
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.starttls.required", "true");
        props.put("mail.smtp.sasl.enable", "true");
        props.put("mail.smtp.sasl.mechanisms", "XOAUTH2");
        props.put("mail.imaps.sasl.mechanisms.oauth2.oauthToken", oauthToken);
        smtpSession = Session.getInstance(props);
        smtpSession.setDebug(debug);

        final URLName unusedUrlName = null;
        SMTPTransport transport = new SMTPTransport(smtpSession, unusedUrlName);
        // If the password is non-null, SMTP tries to do AUTH LOGIN.
        final String emptyPassword = null;
        transport.connect(host, port, userEmail, emptyPassword);

        byte[] responseTemp = String.format("user=%s\1auth=Bearer %s\1\1", userEmail, oauthToken).getBytes();
        byte[] response = BASE64EncoderStream.encode(responseTemp);
        transport.issueCommand("AUTH XOAUTH2 " + new String(response), 235);

        return transport;
}

有关详细信息,请参阅以下链接:Authorizing with Google on AndroidOAuth2 info