Криптоалгоритмы / Описание новой версии API модуля php_xmlsec
.htmОписание новой версии API модуля php_xmlsec @font-face { font-family: Courier; } @font-face { font-family: Verdana; } @page Section1 {size: 595.3pt 841.9pt; margin: 2.0cm 42.5pt 35.95pt 54.0pt; mso-header-margin: 35.4pt; mso-footer-margin: 35.4pt; mso-paper-source: 0; } P.MsoNormal { FONT-SIZE: 12pt; MARGIN: 0cm 0cm 0pt; FONT-FAMILY: "Times New Roman"; mso-ansi-language: EN-US; mso-style-parent: ""; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman" } LI.MsoNormal { FONT-SIZE: 12pt; MARGIN: 0cm 0cm 0pt; FONT-FAMILY: "Times New Roman"; mso-ansi-language: EN-US; mso-style-parent: ""; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman" } DIV.MsoNormal { FONT-SIZE: 12pt; MARGIN: 0cm 0cm 0pt; FONT-FAMILY: "Times New Roman"; mso-ansi-language: EN-US; mso-style-parent: ""; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman" } A:link { COLOR: blue; TEXT-DECORATION: underline; text-underline: single } SPAN.MsoHyperlink { COLOR: blue; TEXT-DECORATION: underline; text-underline: single } A:visited { COLOR: purple; TEXT-DECORATION: underline; text-underline: single } SPAN.MsoHyperlinkFollowed { COLOR: purple; TEXT-DECORATION: underline; text-underline: single } SPAN.m1 { COLOR: blue; mso-style-name: m1 } SPAN.t1 { COLOR: #990000; mso-style-name: t1 } SPAN.ns1 { COLOR: red; mso-style-name: ns1 } SPAN.b1 { FONT-WEIGHT: bold; COLOR: red; TEXT-DECORATION: none; text-underline: none; mso-style-name: b1; mso-ascii-font-family: "Courier New"; mso-hansi-font-family: "Courier New"; mso-bidi-font-family: "Courier New"; mso-text-animation: none; text-line-through: none } DIV.Section1 { page: Section1 } OL { MARGIN-BOTTOM: 0cm } UL { MARGIN-BOTTOM: 0cm } Описание новой версии API модуля php_xmlsec
Введение
Модуль php_xmlsec построен на библиотеке libxmlsec Алексея Санина www.aleksey.com/xmlsec
Особенность libxmlsec – может использовать любые криптобиблиотеки, по умолчанию используется OpenSSL http://www.openssl.org/ Очевидно, при использовании win версии целесообразно использовать криптобиблиотеку ms-crypto, хотя это спорно.
Основные требования
php 5.1, скомпилированно на php 5.1.4 от libxml2- 2.6.12 , скомпилированно с libxml2- 2.6.19 libxslt 1.1.14 OpenSSL 0.9.7 libgcrypt-1.2.1 libgpg-error-1.0 от xmlsec1-1.2.8 ( текущая версия xmlsec1-1.2.9 )
Инсталляция.
Загрузить http://edocs.phpclub.net/xmlsec/xmlsec.zip
Устанавливаем libxmlsec, исходники, RPM на www.aleksey.com/xmlsec, windows версия на сайте Игоря Златкович. Сразу оговорюсь, что на windows не тестировалось. Буду признателен всем, кто сможет помочь скомпилировать и протестировать win версию. очевидно, после установки, необходимо прописать пути, ldconfig – впрочем это как у кого настроенно… копируем папку xmlsec в директорию /usr/local/src/php5.v.xx/ext запускаем make в папке ./modules должен скомпилироваться so-модуль, который необходимо переписать в папку, где хранятся все php-расширения если не определена автоконфигурация модулей, то необходимо прописать в php.ini, впрочем, тем кто смог скомпилировать модуль дальнейшие инструкции не нужны. если не получается скомпилировать модуль, то очевидно Вы где-то напутали с путями, попробуйте переписать папку /usr/local/src/xmlsec1.v.xx/include в папку /usr/include/xmlsec или /usr/local/include/xmlsec а так же см. п.2
Понятие шаблона
Панятие шаблона в криптобиблиотеке libxmlsec является ключевым.
Шаблон – типовая структура xml – докумета, в соответствии с общепринятыми стандартами **, без информационного наполнения данными.
Высокая скорость работы библиотеки libxmlsec достигается за счет использования шаблонов.
Пример шаблона encrypt1-tmpl.xml
Стандарты:
XML Canonicalization and Exclusive XML Canonicalization (W3C recommendations)
http://www.w3.org/TR/xml-c14n/ http://www.w3.org/TR/xml-exc-c14n/ XML Signature (W3C recommendation)
http://www.w3.org/TR/xmldsig-core/ XML Encryption (W3C recommendation)
http://www.w3.org/TR/xmlenc-core/
Как закрыть XML документ
Создать закрытый xml документ можно либо на основе существующего шаблона, либо сгенерить шаблон автоматически.
В данной реализации модуля php_xmlsec закрытие xml документа возможно:
- симметричным алгоритмо: DES, AES
- несимметричным алгоритмом – RSA (публичный и секретный ключи)
Модуль php_xmlsec использует два основных класса:
XMLSecEncryptor – шифровальщик/дешифровальщик XML
XMLSecKey – класс управления ключами.
Пример 1. симметричное шифрование.
Пример шаблона симметричного алгоритма encrypt1-tmpl.xml
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName />
</KeyInfo>
<CipherData>
<CipherValue />
</CipherData>
</EncryptedData>
Данный шаблон должен использовться для шифровании xml документа алгоритмом Triple-DES (тройной DES), длинна симметричного ключа 192 бита. Пусть ключ хранится в БД и передается в PHP переменную ввиде строковой переменной $key_string.
1) создаем экземпляр класса ключа и загружаем его из $key_string методом load()
$key= new XMLSecKey();
$key->load( $key_string , XMLSEC_3DES );
Необходимо отметить, что второй параметр метода load() определяет тип ключа. По умолчанию устанавливается тип XMLSEC_3DES для алгоритма Triple-DES
Для установки типа ключа используются следующие константы:
- XMLSEC_3DES, Тройной DES
- XMLSEC_AES_128 Алгоритм AES для 128-и битного ключа
- XMLSEC_AES_256 Алгоритм AES для 256-ти битного ключа
- XMLSEC_AES_192 Алгоритм AES для 192-х битного ключа
- Использование других констант даст ошибку.
2) создаем экземпляр Шифровальщика ( Энкриптора XMLEncryptor), привязываем к нему ключ и загружаем XMLдокумент.
$enc = new XMLSecEncryptor();
$enc->load( $xmlStrFirst);
$enc->setKey($key);
Переменная $xmlStrFirst является строковым представлением XMLдокумента. В дальнейшем планируется интегрировать в DOM, загрузку будет осуществлять метод $enc->loadXML( $xmlDOMDocement );
3) Загружаем шаблон из xml строки.
$strTemplate = file_get_contents ($fileName);
$enc->loadTemplate( $strTemplate );
4) собственно само шифрование и проверка результата выполнения крипто-операции
try{
$res = $enc->encrypt();
}
catch (Exception $e) {
print $e->getMessage."\n";
}
if ( $res )
print $enc->save();
Значение переменной $res примет true в случае успешного выполнения операции шифрования, иначе false.
Сохранение закрытого XML документа в строку осуществляется методом save();
5) В дальнейшем планируется интегрировать в DOM, выгрузку будет осуществлять метод $xmlDOMDocement = $enc->saveXML();
А также планируется реализовать файловые операции:
$enc->saveToFile ($filename);
$enc->loadFromFile ($filename);
Результат 3des_sym.xml
Пример 2. симметричное шифрование, автоматическое формирование шаблона.
При автоматическом формаровании шаблона Шифровальщиком, соответственно метод loadTemplate(); не используется, а вся информация о структуре шаблона берется из ini настроек, которые задаются в конструкторе в виде ассоциативного массива.
$iniEnc = array(
'id'=>'128',
'EncryptionType'=>'content',
'KeyName' => 'Alexandre',
'EncryptionMethod'=> XMLSEC_3DES,
);
- Ключ 'id' задает значение id аттрибута тега <EncryptedData >
- Ключ 'EncryptionType' может принимать два значения : ‘content’ или ‘element’ (по умолчанию) для аттрибута Type тега <EncryptedData >
- Ключ 'KeyName' задает имя ключа, тег <KeyName />
- Ключ 'EncryptionMethod' определяет алгоритм шифрования, см.п1. Примера 1., является значением аттрибута Algorithm тега <EncryptionMethod />
Создаем эеземпляр класса, иницилизируем его массивом инициализации
$enc = new XMLSecEncryptor($iniEnc);
Далее, вызываются все методы в том же порядке, как в Примере 1, кроме метода загрузки шаблона loadTemplate();.
- загружаем методом load (); XML документ.
- создаем экземпляр ключа, загружаем ключ.
Касательно загрузки ключа, хочется отметить, что симметричный ключ, можно загрузить как из памяти (строковой переменной), так и из файла. В этом случае используется метод loadFromFile();.
$res = $key->loadFromFile('deskey.bin', XMLSEC_KEY_FORMAT_BIN, XMLSEC_DES);
Метод loadFromFile() имеет три параметра:
- имя файла – строковая переменная
- формат ключа, для симметричного ключа используется константа XMLSEC_KEY_FORMAT_BIN
- тип ключа, используются константы XMLSEC_DES или XMLSEC_AES (для алгоритмов DES и AES соответственно). Соответственно, количество бит в файле ключа, должно соответствовать выбранному алгоритму в ini Шифровальщика (Энкриптора ключ EncryptionMethod )
Для установки типа ключа используются следующие константы:
- XMLSEC_3DES, Тройной DES
- XMLSEC_AES_128 Алгоритм AES для 128-и битного ключа
- XMLSEC_AES_256 Алгоритм AES для 256-ти битного ключа
- XMLSEC_AES_192 Алгоритм AES для 192-х битного ключа
- Использование других констант даст ошибку.
Далее привязываем класс Ключа к Шифровальщику и выполняем шифрование методом encrypt() и сохраняем результат методом save(). Все как в Примере 1.
Текст исходника …
Пример 3, Шифрование методом RSA
Шифрование методом RSA предполагает наличие пары ключей, одним ключом происходит шифрование, а вторым дешифровка данных. В отличие от симметричного шифрования, когда ключ мы можем загрузить как из памяти, так и из файла, при шифровании методом RSA мы загружаем ключ только из файла, методом $key->loadFromFile('rsakey.pem', XMLSEC_KEY_FORMAT_PEM );
Так же, необходимо отметить, что хранение RSA ключей, как правило происходит в двух основных форматах, DER и PEM. Для загрузки ключа в формате DER используется константа XMLSEC_KEY_FORMAT_DER, для формата PEM XMLSEC_KEY_FORMAT_PEM соответственно.
Алгоритм RSA – предполагает шифрование сессионным ключом, которрый шифруется и передаается вместе с зашифрованным документом. Алгоритм шифрования сессионного ключа определяется в ini параметра ключом ассоциативного массива : 'EncryptedKeyAlgorithm'
Данный параметр может принимать два значения, соответствующим алгоритмам (RFC 2437):
- XMLSEC_EN_RSA_1_5, алгоритм RSA v 1.5
- XMLSEC_EN_RSA_OAEP_MGF1P, алгоритм RSA OAEP
$iniEnc = array(
'id'=>'128',
'KeyName' => 'Alexandre',
'EncryptionMethod'=> XMLSEC_3DES,
'EncryptedKeyAlgorithm' => XMLSEC_EN_RSA_1_5,
);
$enc = new XMLSecEncryptor($iniEnc);
$enc->load( $xmlStrFirst);
$key= new XMLSecKey();
try{
$res = $key->loadFromFile('rsakey.pem', XMLSEC_KEY_FORMAT_PEM );
if (!$res) { var_dump($res); print 'key is empty'; }
}
catch (Exception $e) {
print $e->getMessage."\n";
}
$enc->setKey($key);
try{
$enc->