藉由使用 CDOSYS/CDOEX 如何傳送數位簽章的郵件

文章翻譯 文章翻譯
文章編號: 280391 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

結論

Microsoft 共同作業資料物件的 Windows 2000 (CDOSYS) 和 Microsoft 共同作業資料物件的 [Exchange 2000] (CDOEX) 並不會直接提供能夠加上數位簽章或加密訊息。應用程式發展介面 (API) 未公開任何功能,以產生有效的簽章。但是,您可以搭配 CDOSYS 或 CDOEX 使用密碼編譯 API 及 (或經過數位簽署) 加密訊息。

其他相關資訊

您可以使用 COM 版本的密碼編譯 API (CAPICOM) 和 (或輕易地簽署) CDOSYS 或 CDOEX 郵件加密。您可以從下列 Microsoft 取得 CAPICOM DLL 」 平台 SDK Redistributable: CAPICOM 1.0A 」 網站:
http://www.microsoft.com/downloads/details.aspx?FamilyID=860ee43a-a843-462f-abb5-ff88ea5896f6&DisplayLang=en

數位簽章訊息

  1. 開頭是 CDOSYS 或 CDOEX IMessage 物件。使用寄件者、 收件者、 主旨、 本文、 附件,以及任何其他必要的項目來設定此訊息。
  2. 建立新的 IMessage 物件。使用此新訊息 IDatasource::OpenObject 方法,從步驟 1 開啟現有的郵件。
  3. 取得新的 IMessage 物件 IBodyPart 根目錄,然後設定下列內容:
    oBodyPart.ContentMediaType = "application/pkcs7-mime;smime-type=signed-data;name=""smime.p7m"""
    oBodyPart.ContentTransferEncoding = "base64"
    oBodyPart.Fields("urn:schemas:mailheader:content-disposition") = "attachment;FileName=""smime.p7m"""
    oBodyPart.Fields.Update
    					
  4. 使用 CAPICOM 簽署者物件和寄件者的憑證簽署新 IMessage 物件的內容。
  5. 傳送新郵件,並再捨棄原始的訊息。

加密訊息

  1. 開頭是 CDOSYS 或 CDOEX IMessage 物件。使用寄件者、 收件者、 主旨、 本文、 附件,以及任何其他必要的項目來設定此訊息。
  2. 建立新的 IMessage 物件。使用此新訊息 IDatasource::OpenObject 方法,從步驟 1 開啟現有的郵件。
  3. 取得新的 IMessage 物件 IBodyPart 根目錄,然後設定下列內容:
    oBodyPart.ContentMediaType = "application/pkcs7-mime;smime-type=enveloped-data;name=smime.p7m;"
    oBodyPart.ContentTransferEncoding = "base64"
    oBodyPart.Fields("urn:schemas:mailheader:content-disposition") = "attachment;FileName=""smime.p7m"""
    oBodyPart.Fields.Update
    					
  4. 使用 CAPICOM EnvelopedData 物件和收件者憑證加密新 IMessage 物件的內容。
  5. 傳送新郵件,並捨棄原始。

數位簽章與加密訊息

步驟相同,但順序是很重要的。您必須先簽章此訊息,並加密訊息。

範例程式碼

範例程式碼的相關附註

  • 這個範例呼叫兩個不存在函式,GetCertForSignatureGetCertForEnvelope。程式設計師必須取得適當的憑證。
  • 範例程式碼需要 CAPICOM 1.0 型別程式庫、 [Microsoft ActiveX 資料物件] 2.5 櫃和適當的 CDO 程式庫的參考。
'******************************************************************
'
' SignMessage
'
' Takes oMsg as input (non-secure message) and returns a new
' message that is digitally signed.
'
'******************************************************************
Public Function SignMessage(oMsg As CDO.Message) As CDO.Message
    Dim oSecMsg As New CDO.Message
    Dim oBodyPart As CDO.IBodyPart
    Dim oSignedData As New CAPICOM.SignedData
    Dim strData As String
    Dim strContent As String
    Dim oStream As ADODB.Stream
    Dim oSigner As New CAPICOM.Signer
    Dim oCert As CAPICOM.Certificate
    Dim oAttr As New CAPICOM.Attribute
    Dim byteData() As Byte
    
    On Error GoTo handle_error
    
    ' Copy input into output message
    oSecMsg.DataSource.OpenObject oMsg, cdoIMessage
    
    ' Set up main bodypart
    Set oBodyPart = oSecMsg.BodyPart
    oBodyPart.ContentMediaType = "application/pkcs7-mime;smime-type=signed-data;name=""smime.p7m"""
    oBodyPart.ContentTransferEncoding = "base64"
    oBodyPart.Fields("urn:schemas:mailheader:content-disposition") = "attachment;FileName=""smime.p7m"""
    oBodyPart.Fields.Update
            
    ' Get certificate
    Set oCert = GetCertForSignature(oSecMsg.From)
    
    ' If no cert, throw an error and exit
    If oCert Is Nothing Then
        MsgBox "No valid certificate found for sender.", , "Error"
        Set SignMessage = Nothing
    End If
    
    ' Add cert to signer object
    oSigner.Certificate = oCert
    
    ' Add signing time attribute to signer object
    oAttr.Name = CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME
    oAttr.Value = Now
    oSigner.AuthenticatedAttributes.Add oAttr

    ' Sign the content (root bodypart)
    strContent = oMsg.BodyPart.GetStream.ReadText
    oSignedData.Content = StrConv(strContent, vbFromUnicode)

    strData = oSignedData.Sign(oSigner, False, CAPICOM_ENCODE_BINARY)

    ' Write the cms blob into the main bodypart
    ' let CDO do the base64 encoding
    Set oStream = oSecMsg.BodyPart.GetDecodedContentStream
    
    oStream.Type = adTypeBinary

    ' Get the string data as a byte array
    byteData = strData
    
    ' Write the data to the stream and flush it
    oStream.Write byteData
    oStream.Flush
    
    GoTo cleanup
    
    ' Report error
handle_error:
    MsgBox Err.Number & ": " & Err.Description, , "Error:"
    Set oSecMsg = Nothing
    
    ' Clean up memory
cleanup:
    Set oBodyPart = Nothing
    Set oSignedData = Nothing
    Set oStream = Nothing
    Set oSigner = Nothing
    Set oCert = Nothing
    Set oAttr = Nothing
    
    ' Return new message
    Set SignMessage = oSecMsg
End Function

'******************************************************************
'
' EnvelopeMessage
'
' Takes oMsg as input (non-secure message) and returns a new
' message that is enveloped.
'
'******************************************************************
Public Function EnvelopeMessage(oMsg As CDO.Message, iCertStore As Integer, Optional strQuery As String) As CDO.Message
    Dim oSecMsg As New CDO.Message
    Dim oBodyPart As CDO.IBodyPart
    Dim oEnvelopedData As New CAPICOM.EnvelopedData
    Dim oCert As CAPICOM.Certificate
    Dim oStream As ADODB.Stream
    Dim strData As String
    Dim strContent As String
    Dim byteData() As Byte
    
    ' Copy input into output message
    oSecMsg.DataSource.OpenObject oMsg, cdoIMessage
    
    ' Set up main bodypart
    Set oBodyPart = oSecMsg.BodyPart
    oBodyPart.ContentMediaType = "application/pkcs7-mime;smime-type=enveloped-data;name=smime.p7m;"

    oBodyPart.ContentTransferEncoding = "base64"
    oBodyPart.Fields("urn:schemas:mailheader:content-disposition") = "attachment;FileName=""smime.p7m"""
    oBodyPart.Fields.Update
    
    ' Get recipient's cert
    If strQuery = "" Then
        Set oCert = GetCertForEnvelope(oSecMsg.To, iCertStore)
    Else
        Set oCert = GetCertForEnvelope(oSecMsg.To, iCertStore, strQuery)
    End If
    
    oEnvelopedData.Recipients.Add oCert
    
    ' Encrypt content
    strContent = oMsg.BodyPart.GetStream.ReadText
    oEnvelopedData.Content = StrConv(strContent, vbFromUnicode)
    strData = oEnvelopedData.Encrypt(CAPICOM_ENCODE_BINARY)
    
    ' Write the CMS blob into the main bodypart
    ' let CDO do the base64 encoding
    Set oStream = oSecMsg.BodyPart.GetDecodedContentStream
    
    oStream.Type = adTypeBinary
    
    ' Get the string data as a byte array
    byteData = strData
    
    ' Write the data to the stream and flush it
    oStream.Write byteData
    oStream.Flush
    
    GoTo cleanup
    
handle_error:
    MsgBox Err.Number & ": " & Err.Description, , "Error:"
    Set oSecMsg = Nothing
    
    ' Clean up memory
cleanup:
    Set oBodyPart = Nothing
    Set oEnvelopedData = Nothing
    Set oStream = Nothing
    Set oCert = Nothing
    
    ' Return new message
    Set EnvelopeMessage = oSecMsg
End Function
				

屬性

文章編號: 280391 - 上次校閱: 2007年10月25日 - 版次: 4.5
這篇文章中的資訊適用於:
  • Microsoft Exchange Server 2003 Enterprise Edition
  • Microsoft Exchange Server 2003 Standard Edition
  • Microsoft Exchange 2000 Server Standard Edition
  • Microsoft Windows Server 2003, Enterprise Edition (32-bit x86)
  • Microsoft Windows Server 2003, Standard Edition (32-bit x86)
  • Microsoft Windows 2000 Advanced Server
  • Microsoft Windows 2000 Server
  • Microsoft Windows 2000 Professional Edition
  • Microsoft Windows XP Professional
  • Microsoft Windows XP Home Edition (家用版)
  • Collaboration Data Objects for Exchange 2000
  • Microsoft Collaboration Data Objects 2.0
關鍵字:?
kbmt kbenv kbhowto kbmsg KB280391 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:280391
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com