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» центра загрузки Майкрософт по адресу:
Загрузите объект CDOSYS или CDOEX IMessage. Настройте параметры сообщения, такие как отправитель, получатель, тема, вложения и прочие необходимые элементы.
Создайте новый объект IMessage. Откройте сообщение, созданное на первом шаге при помощи метода IDatasource::OpenObject из нового объекта.
Получите корень объекта IBodyPart нового сообщения IMessage и установите следующие параметры:
Используйте объект CAPICOM Signer и сертификат отправителя для шифрования содержимого нового объекта IMessage.
Отправьте новое сообщение, а затем удалите оригинал.
Шифрование сообщения
Загрузите объект CDOSYS или CDOEX IMessage. Настройте параметры сообщения, такие как отправитель, получатель, тема, вложения и прочие необходимые элементы.
Создайте новый объект IMessage. Откройте сообщение, созданное на первом шаге при помощи метода IDatasource::OpenObject из нового объекта.
Получите корень объекта IBodyPart нового сообщения IMessage и установите следующие параметры:
Используйте объект CAPICOM EnvelopedData и сертификат получателя для шифрования содержимого нового объекта IMessage.
Отправьте новое сообщение, а затем удалите оригинал.
Создание цифровой подписи и шифрование сообщения
Для этого используются те же самые шаги, однако в данном случае очень важен порядок выполнения действий. Сначала сообщение подписывается, а затем шифруется.
Пример кода
Замечания к примеру кода
Пример вызывает две несуществующие функции, 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
Насколько сложно Вам было следовать инструкциям из этой статьи?
Очень просто
Просто
Немного сложно
Сложно
Очень сложно
Оставьте свой отзыв о качестве предоставляемых нами сведений и предложения по их улучшению.
Спасибо! Благодаря вашему отзыву мы сможем сделать справочные материалы еще лучше. Чтобы воспользоваться дополнительными возможностями поддержки, посетите домашнюю страницу центра справки и поддержки.