获取S / MIME签名邮件的附件

时间:2018-08-22 07:37:57

标签: microsoft-graph

我正在尝试通过microsoft-graph-api获取签名邮件的附件。

我在此URL上使用了 GET-请求

https://graph.microsoft.com/v1.0/me/messages/AAMkAG.../attachments

这应该返回指定邮件的对象列表。每个对象都包含一个附件的元数据,例如“ 名称”和“ contentType ”,以及包含内容内容的属性“ contentBytes ”附件为base64-string

如果邮件没有附件,则此列表为空。

到目前为止,对于所有未通过S/MIME签名的邮件,此方法都可以正常使用。
但是,如果邮件是用S/MIME签名的,则响应列表中会出现奇怪的结果。

无论邮件有多少个附件,响应列表都只包含一个元素。然后,此元素带有名称“ smime.p7m ”和contentType“ multipart / signed ”,而contentBytes属性几乎包含邮件的整个MIME,而不是内容单个附件。

我无法想象这是期望的行为,所以我问:

这是microsoft-graph-api中的错误还是我在请求中做错了?如果是,我该如何解决?

2 个答案:

答案 0 :(得分:1)

这可能与您的问题无关,但是我花了3天的时间尝试从已签名但未加密的电子邮件中提取附件。希望这对处于类似情况的人有所帮助。 以下是在vb.net中对我有用的步骤:

  1. 安装Mimekit Nuget Package
  2. 通过查看其内容类型和附件名称正确识别S / Mime签名的电子邮件(S / Mime签名的电子邮件始终始终附有smime.p7m文件)
If String.Equals(origMessage.Attachments.First.ContentType, "multipart/signed", 
StringComparison.OrdinalIgnoreCase) AndAlso
String.Equals(origMessage.Attachments.First.Name, "smime.p7m", StringComparison.OrdinalIgnoreCase) Then
  1. 将smime文件加载为EWS FileAttachment,并从中创建新的memoryStream。然后创建此流的MimeKit.MimeEntity。现在,您正在使用MimeKit库,该库非常适合这些东西
Dim smimeFile As FileAttachment = origMessage.Attachments.First
smimeFile.Load()
Dim memoryStreamSigned As MemoryStream = New MemoryStream(smimeFile.Content)
Dim entity = MimeEntity.Load(memoryStreamSigned)
  1. 遍历您的MimeEntity实例以获取所有附件
If TypeOf entity Is Cryptography.MultipartSigned Then
    Dim mltipart As Multipart = entity
    Dim attachments As MimeEntity = mltipart(0)
    If TypeOf attachments Is Multipart Then
        Dim mltipartAttachments As Multipart = attachments
        For i As Integer = 0 To mltipartAttachments.Count - 1
            If mltipartAttachments(i).IsAttachment Then
                **'BOOM, now you're looping your attachment files one by one**
                **'Call your decode function to read your attachment as array of Bytes**
            End If
        Next
    End If
End If
  1. 将附件读取为字节数组。在上一步的for中执行此操作。
'Read and decode content stream
Dim fileStrm = New MemoryStream()
mltipartAttachments(i).Content.DecodeTo(fileStrm)

Dim decodedBytes(0 To fileStrm.Length - 1) As Byte
fileStrm.Position = 0  'This is important because .DecodeTo set the position to the end!!
fileStrm.Read(decodedBytes, 0, Convert.ToInt32(fileStrm.Length))

现在,您已将附件文件解码为字节数组,您可以保存它或做任何您想做的事情:)希望对您有所帮助!

答案 1 :(得分:0)

这不是错误,而是在出现“多部分/已签名”消息的情况下的预期行为。

来自RFC5751(第26页的底部):

  

多部分/已签名媒体类型分为两部分。第一部分      包含已签名的MIME实体;第二部分包含      “分离的签名” CMS SignedData对象在其中      encapContentInfo eContent字段不存在。

因此,已签名的内容(包括所有附件)都存储在一个smime.p7m附件中。您可以提取它。

假设您使用的是.Net,则可以使用SignedCms类来验证签名并使用ContentInfo属性检索内容。