Как послать сообщение, имеющее цифровую подпись, при помощи CDOSYS/CDOEX

Код статьи: 280391 - Список продуктов, к которым относится данная статья.
Данная статья была ранее опубликована под номером RU280391
Развернуть все | Свернуть все

На этой странице

Аннотация

Microsoft Collaboration Data Objects для Windows 2000 (CDOSYS) и Microsoft Collaboration Data Objects для Exchange 2000 (CDOEX) напрямую не предоставляют возможность установить цифровую подпись на сообщение или зашифровать его. Прикладной программный интерфейс (API) не обеспечивает возможность генерирования надежных подписей. Несмотря на это для создания цифровой подписи или шифрования сообщения можно использовать интерфейс «Cryptography API» в сочетании с CDOSYS или CDOEX.

Дополнительная информация

С помощью версии COM криптографического прикладного программного интерфейса (CAPICOM) можно легко создавать подписи и шифровать сообщения CDOSYS или CDOEX. Файл CAPICOM.DLL можно загрузить на веб-странице «Свободно распространяемый набор разработчика Platform SDK CAPICOM» центра загрузки Майкрософт по адресу:
http://www.microsoft.com/downloads/details.aspx?displaylang=ru&FamilyID=860ee43a-a843-462f-abb5-ff88ea5896f6

Создание цифровой подписи сообщения

  1. Загрузите объект CDOSYS или CDOEX IMessage. Настройте параметры сообщения, такие как отправитель, получатель, тема, вложения и прочие необходимые элементы.
  2. Создайте новый объект IMessage. Откройте сообщение, созданное на первом шаге при помощи метода IDatasource::OpenObject из нового объекта.
  3. Получите корень объекта IBodyPart нового сообщения IMessage и установите следующие параметры:
    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 Signer и сертификат отправителя для шифрования содержимого нового объекта IMessage.
  5. Отправьте новое сообщение, а затем удалите оригинал.

Шифрование сообщения

  1. Загрузите объект CDOSYS или CDOEX IMessage. Настройте параметры сообщения, такие как отправитель, получатель, тема, вложения и прочие необходимые элементы.
  2. Создайте новый объект IMessage. Откройте сообщение, созданное на первом шаге при помощи метода IDatasource::OpenObject из нового объекта.
  3. Получите корень объекта IBodyPart нового сообщения IMessage и установите следующие параметры:
    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. Отправьте новое сообщение, а затем удалите оригинал.

Создание цифровой подписи и шифрование сообщения

Для этого используются те же самые шаги, однако в данном случае очень важен порядок выполнения действий. Сначала сообщение подписывается, а затем шифруется.

Пример кода

Замечания к примеру кода

  • Пример вызывает две несуществующие функции, GetCertForSignature и GetCertForEnvelope. Разработчик должен получить подходящий сертификат.
  • Пример кода требует установить ссылки на библиотеки CAPICOM 1.0 Type Library, Microsoft ActiveX Data Objects 2.5 Library и соответствующую библиотеку CDO Library.
'******************************************************************
'
' Подпись_сообщения
'
' Получаем в качестве источника oMsg (неподписанное сообщение) и возвращаем новое
' сообщение, имеющее цифровую подпись.
'
'******************************************************************
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
    
    ' Копируем данные в новое сообщение
    oSecMsg.DataSource.OpenObject oMsg, cdoIMessage
    
    ' Устанавливаем основную часть
    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
            
    ' Получаем сертификат
    Set oCert = GetCertForSignature(oSecMsg.From)
    
    ' При отсутствии сертификата возвращаем ошибку и выходим
    If oCert Is Nothing Then
        MsgBox "No valid certificate found for sender.", , "Error"
        Set SignMessage = Nothing
    End If
    
    ' Добавляем сертификат к подписанному объекту
    oSigner.Certificate = oCert
    
    ' Добавляем время подписи и атрибут подписанного объекта
    oAttr.Name = CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME
    oAttr.Value = Now
    oSigner.AuthenticatedAttributes.Add oAttr

    ' Подписываем содержание (корневая основная часть)
    strContent = oMsg.BodyPart.GetStream.ReadText
    oSignedData.Content = StrConv(strContent, vbFromUnicode)

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

    ' Записываем большой двоичный объект cms в основную часть
    ' Устанавливаем шифрование основанное на base64 через CDO
    Set oStream = oSecMsg.BodyPart.GetDecodedContentStream
    
    oStream.Type = adTypeBinary

    ' Получаем строку данных в качестве массива байт
    byteData = strData
    
    ' Записываем данные в поток и выполняем его очистку
    oStream.Write byteData
    oStream.Flush
    
    GoTo cleanup
    
    ' Отсылаем отчет об ошибке
handle_error:
    MsgBox Err.Number & ": " & Err.Description, , "Error:"
    Set oSecMsg = Nothing
    
    ' Выполняем очистку памяти
cleanup:
    Set oBodyPart = Nothing
    Set oSignedData = Nothing
    Set oStream = Nothing
    Set oSigner = Nothing
    Set oCert = Nothing
    Set oAttr = Nothing
    
    ' Возвращаем новое сообщение
    Set SignMessage = oSecMsg
End Function

'******************************************************************
'
' Запечатываем сообщение
'
' Получаем в качестве источника oMsg (неподписанное сообщение) и возвращаем новое
' запечатанное сообщение.
'
'******************************************************************
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
    
    ' Копируем данные в новое сообщение
    oSecMsg.DataSource.OpenObject oMsg, cdoIMessage
    
    ' Устанавливаем основную часть
    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
    
    ' Получаем сертификат получателя
    If strQuery = "" Then
        Set oCert = GetCertForEnvelope(oSecMsg.To, iCertStore)
    Else
        Set oCert = GetCertForEnvelope(oSecMsg.To, iCertStore, strQuery)
    End If
    
    oEnvelopedData.Recipients.Add oCert
    
    ' Зашифровываем содержимое
    strContent = oMsg.BodyPart.GetStream.ReadText
    oEnvelopedData.Content = StrConv(strContent, vbFromUnicode)
    strData = oEnvelopedData.Encrypt(CAPICOM_ENCODE_BINARY)
    
    ' Записываем большой двоичный объект CMS в основную часть
    ' Устанавливаем шифрование основанное на base64 через CDO
    Set oStream = oSecMsg.BodyPart.GetDecodedContentStream
    
    oStream.Type = adTypeBinary
    
    ' Получаем строку данных в качестве массива байт
    byteData = strData
    
    ' Записываем данные в поток и выполняем его очистку
    oStream.Write byteData
    oStream.Flush
    
    GoTo cleanup
    
handle_error:
    MsgBox Err.Number & ": " & Err.Description, , "Error:"
    Set oSecMsg = Nothing
    
    ' Выполняем очистку памяти
cleanup:
    Set oBodyPart = Nothing
    Set oEnvelopedData = Nothing
    Set oStream = Nothing
    Set oCert = Nothing
    
    ' Возвращаем новое сообщение
    Set EnvelopeMessage = oSecMsg
End Function
				

Свойства

Код статьи: 280391 - Последнее изменение :: 26 ноября 2007 г. - Редакция: 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
  • Microsoft Windows XP Professional
  • Microsoft Windows XP Home Edition
  • Collaboration Data Objects for Exchange 2000
  • Microsoft Collaboration Data Objects 2.0
Ключевые слова: 
kbhowto kbmsg kbenv KB280391

Отправить отзыв