четверг, 7 февраля 2008 г.

SOAP и веб-сервисы XML на платформе .Net

"SOAP и веб-сервисы XML на платформе .Net" -- это первая моя статья вышедшая в печатном издании. Чему я очень рад.



Анонс на сайте журнала «Системный администратор».

среда, 23 января 2008 г.

OpenPGP для C# .Net (3). Удаление (добавление) ключа из хранилища

Вы уже знаете, как можно узнать какие ключи находятся в хранилище из заметки «Просмотр хранилища ключей»


Теперь рассмотрим, как можно удалить и добавить связку ключей в хранилище.



На деле, удаление и добавление связки ключей, очень похожие операции. Поэтому для краткости и упрощения кода будем удалять связку -- для добавления нам бы потребовалось в начале создать ключи.


И так, первым делом прочитаем хранилище ключей. Эта операция вам уже знакома по первым двум статьям цикла.



// путь до хранилища секретных ключей
string path = @"secring_bak3.gpg";
           
// прочитаем хранилище ключей
Stream BundleStream = File.OpenRead(path);
BundleStream =
        PgpUtilities.GetDecoderStream(BundleStream);

PgpSecretKeyRingBundle pgpSec =
        new PgpSecretKeyRingBundle(BundleStream);
           
BundleStream.Close()Syhi-подсветка кода
;


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



// получим связку ключей по уникальному ID
long keyId = -7764185142489588446;
PgpSecretKeyRing pgpKeyRing =
        pgpSec.GetSecretKeyRing(keyId);

Непосредственно удаление:

pgpSec = PgpSecretKeyRingBundle.RemoveSecretKeyRing(
        pgpSec, pgpKeyRing);

/*
вот как выглядит добавление ключа
PgpSecretKeyRingBundle.AddSecretKeyRing(pgpSec, pgpKeyRing);
*/
Syhi-подсветка кода



Вот и все, осталось только сохранить изменения. Для этого надо лишь передать методу Encode() объекта хранилища ключей поток и он запишет в него нужную информацию.



// Запишем хранилище ключей
Stream NewBundleStream = File.OpenWrite(@"new_secring_bak.gpg");
pgpSec.Encode(NewBundleStream);
NewBundleStream.Close();Syhi-подсветка кода



Соберем все вместе.



using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using Org.BouncyCastle.Bcpg;
using Org.BouncyCastle.Bcpg.OpenPgp;

namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
        Console.WriteLine("**Удаление связки ключей**\n");
           
        // путь до хранилища секретных ключей
        string path = @"secring_bak3.gpg";
           
        // прочитаем хранилище ключей
        Stream BundleStream = File.OpenRead(path);
        BundleStream =
                PgpUtilities.GetDecoderStream(BundleStream);

        PgpSecretKeyRingBundle pgpSec =
                new PgpSecretKeyRingBundle(BundleStream);
           
        BundleStream.Close();
           
           
        // получим связку ключей по уникальному ID
        long keyId = -7764185142489588446;
        PgpSecretKeyRing pgpKeyRing =
                pgpSec.GetSecretKeyRing(keyId);

        // удалим связку
        pgpSec =
                PgpSecretKeyRingBundle.RemoveSecretKeyRing
                (pgpSec, pgpKeyRing);
               
        // Запишем хранилище ключей
        Stream NewBundleStream =
                File.OpenWrite(@"new_secring_bak.gpg");
               
        pgpSec.Encode(NewBundleStream);
        NewBundleStream.Close();
 
        Console.ReadLine();
}}}Syhi-подсветка кода


вторник, 8 января 2008 г.

Клиент для web-сервиса XML на FLEX.

В данной заметке мы создадим простой web-сервис на C# .Net, а клиентом для нашего сервиса послужит FLEX приложение.



Подробное описание создания и принципов функционирования сервисов XML не входит в рамки данной статьи. Предполагается, что вы обладаете начальными знаниями:
- знаете, как создать web-сервис Hello World (такой сервис создается средой Visual Studio 2005 автоматически, стоит только выбрать File -> New -> Web Site -> ASP.NET web Service);
- на вашей машине установлен IIS (Internet Information Server) и вы знаете, как создать виртуальный каталог и разместить в нем web-сервис;
- вы обладаете навыками работы с flex.


Приступим. Наш сервис будет принимать строку с именем пользователя и «здороваться» – т.е. возвращать строку “Здравствуйте” + введенное имя.



using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
    public Service () {}

    [WebMethod]
    public string HelloWorld(string name) {
        return "Здравствуйте, " + name;
    }
}Syhi-подсветка кода



Сервис содержит единственный метод HelloWorld(), который помечен атрибутом [WebMethod] и значит, может быть вызван удаленным приложением. Именно этот метод и будет вызывать Flex приложение.
Опубликуйте сервис по адресу http://localhost/soap1/service.asmx


Теперь создадим клиента на Flex. Нужно использовать <mx:WebService> тег.



<mx:WebService id="s"
  wsdl="http://localhost/soap1/service.asmx?WSDL"
  fault="ДЕЙСТВИЕ_ПРИ_ОШИБКЕ">


  <mx:operation name="ИМЯ_ВЫЗЫВАЕМОГО_МЕТОДА"
    resultFormat="object">

    <mx:request>
    <!-- Здесь необходимо указать параметры
    вызываемого метода -->

    </mx:request>
  </mx:operation>
 
</mx:WebService>Syhi-подсветка кода



Лучше один раз увидеть, чем сто раз услышать:



Осталось добавить недостающие элементы: поле ввода, кнопку и лайбл для вывода результата.



<mx:TextInput id="input1" text="name"
  x="10" y="10"/>


<!-- кнопка для отправки запроса -->
<mx:Button id="button" click="s.HelloWorld.send()"
  x="178" y="10" label="Ok"/>


<!-- лайбл для вывода ответа сервиса -->
<mx:Label id="res" text="{s.HelloWorld.lastResult}"
  x="10" y="85" width="210"/>
Syhi-подсветка кода



Соберем весь код вместе:



<?xml version="1.0" encoding="utf-8"?>
<!-- пример клиента для web-сервиса XML -->
<mx:Application
  xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">


  <mx:WebService id="s"
    wsdl="http://localhost/soap1/service.asmx?WSDL"
    fault="{res.text = 'ОШИБКА!'}">


    <mx:operation name="HelloWorld" resultFormat="object">
      <mx:request>
        <name>{input1.text}</name>
      </mx:request>
    </mx:operation>
       
  </mx:WebService>

  <mx:TextInput x="10" y="10" id="input1"
    text="name"/>

  <mx:Button x="178" y="10" label="Ok" id="button"
    click="s.HelloWorld.send()"/>

  <mx:Label x="10" y="59" text="Ответ сервиса:"
    id="label1" fontWeight="bold"/>

  <mx:Label x="10" y="85" text="{s.HelloWorld.lastResult}"
    width="210" id="res"/>

       
</mx:Application>Syhi-подсветка кода


суббота, 29 декабря 2007 г.

OpenPGP для C# .Net (2). Подписание строки (ЭЦП)

В данной заметке мы выдадим ЭЦП для произвольной строки. Результатом работы нашей программы будет файл, содержащий подпись в формате openPGP, оформленный по всем стандартам.



Как и в первой статье цикла («OpenPGP для C# .Net (1). Просмотр хранилища ключей») будем использовать библиотеку от «The Legion of the Bouncy Castle».


Вы уже знаете как обращаться с хранилищем секретных ключей:



// путь до хранилища секретных ключей
string path = @"secring_bak.gpg";
           
// прочитаем хранилище ключей
Stream BundleStream  =  File.OpenRead(path);
BundleStream  =  PgpUtilities.GetDecoderStream(BundleStream);
           
PgpSecretKeyRingBundle pgpSec  = new PgpSecretKeyRingBundle(BundleStream);Syhi-подсветка кода


Теперь нужно найти ключ, на котором мы будем подписывать. Напомню, что PGP-ключ состоит из 2-х половинок: секретного и открытого ключей.
Для того чтобы использовать секретную половинку нужно указать пароль доступа. Приведенный ниже код выполняет поиск PGP-ключа и указывает пароль для секретной половинки.



// отыщем ключ по уникальному идентификатору
long keyId = -7764185142489588446;
PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyId);
           
// для доступа к секретному ключу нужно указать пароль
string pass = "1";
PgpPrivateKey pgpPrivKey =
    pgpSecKey.ExtractPrivateKey(pass.ToCharArray());Syhi-подсветка кода


Далее следует создать объект генератора подписи, предварительно выбрав алгоритм хеширования:



// для генерации подписи нужно выбрать
// функцию хеширования, в данном случае Sha1
HashAlgorithmTag digest = HashAlgorithmTag.Sha1;

// создадим объект генератора подписи
PgpSignatureGenerator sGen = new PgpSignatureGenerator(
    pgpSecKey.PublicKey.Algorithm, digest);

sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey);Syhi-подсветка кода


На этом подготовительные операции заканчиваются. Определим строку, которую хотим подписать, а также файл для хранения подписи в нужном формате. Корректность подписи из такого файла можно проверить стандартными средствами, например для windows можно использовать winPT.



// строку, которую будем подписывать,
// необходимо представить в виде массива байт
string str = "12привет";
byte[] byteStr = Encoding.UTF8.GetBytes(str);

// файл для хранения прозрачной подписи
Stream fos = File.Create("my_sign.asc");

// непосредственно подписание
sGen.Update(byteStr);

// формирование файла, нужного вида
ArmoredOutputStream aOut = new ArmoredOutputStream(fos);
aOut.BeginClearText(digest);
aOut.Write(byteStr);
aOut.Write((byte)'\r');
aOut.Write((byte)'\n');
aOut.EndClearText();
BcpgOutputStream bOut = new BcpgOutputStream(aOut);
           
sGen.Generate().Encode(bOut);Syhi-подсветка кода


Собирем весь код вместе:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using Org.BouncyCastle.Bcpg;
using Org.BouncyCastle.Bcpg.OpenPgp;
using System.Collections;


namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
    Console.WriteLine("**Подпишим строку**\n");

    // путь до хранилища секретных ключей
    string path = @"secring_bak.gpg";

    // прочитаем хранилище ключей
    Stream BundleStream = File.OpenRead(path);
    BundleStream =
        PgpUtilities.GetDecoderStream(BundleStream);

    PgpSecretKeyRingBundle pgpSec =
        new PgpSecretKeyRingBundle(BundleStream);

    // отыщем ключ по уникальному идентификатору
    long keyId = -7764185142489588446;
    PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyId);

    // для доступа к секретному ключу нужно указать пароль
    string pass = "pass";
    PgpPrivateKey pgpPrivKey =
        pgpSecKey.ExtractPrivateKey(pass.ToCharArray());


    // для генерации подписи нужно выбрать
    // функцию хеширования, в данном случаи Sha1
    HashAlgorithmTag digest = HashAlgorithmTag.Sha1;
    PgpSignatureGenerator sGen = new PgpSignatureGenerator(
        pgpSecKey.PublicKey.Algorithm, digest);


    sGen.InitSign(
        PgpSignature.CanonicalTextDocument, pgpPrivKey);

    // строку, которую будем подписывать,
    // необходимо представить в виде массива байт
    string str = "12привет";
    byte[] byteStr = Encoding.UTF8.GetBytes(str);

    // файл для хранения прозрачной подписи
    Stream fos = File.Create("my_sign.asc");

    // непосредственно подписание
    sGen.Update(byteStr);

    // формирование файла, нужного вида
    ArmoredOutputStream aOut = new ArmoredOutputStream(fos);
    aOut.BeginClearText(digest);
    aOut.Write(byteStr);
    aOut.Write((byte)'\r');
    aOut.Write((byte)'\n');
    aOut.EndClearText();
    BcpgOutputStream bOut = new BcpgOutputStream(aOut);

    sGen.Generate().Encode(bOut);


    aOut.Close();
    fos.Close();

    Console.ReadLine();
}}}Syhi-подсветка кода


В итоге у нас получился файл следующего вида:



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

12привет
-----BEGIN PGP SIGNATURE-----
Version: BCPG v1.32

iEYEARECAAYFAkd2NP0ACgkQlEASv9OK3SL0+wCeNq2PKsTZcGmJzbixpcMx8N1J
bSIAoKX9ERFgDOJaPO6FWm1OcBGbudaV
=Hw18
-----END PGP SIGNATURE-----

среда, 26 декабря 2007 г.

OpenPGP для C# .Net (1). Просмотр хранилища ключей

Данная заметка первая из планируемого цикла по использованию криптографических стандартов openPGP на платформе .Net. Предполагается, что вы знаете, что это такое и обладаете базовыми знаниями криптографии (получить эти знания на русском можно на страницах http://www.pgpru.com/).



Первым делом скачайте последнюю версию bccrypto-net, которую предлагает проект «The Legion of the Bouncy Castle» (большое им спасибо).


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


Для начала это хранилище нужно создать. Для создания и хранения ключей PGP на ос Windows есть удобная программа с графическим интерфейсом – winPT. Каждый раз, после добавления нового ключа, программа предлагает сохранить копию хранилища ключей в удобном для вас месте (по умолчанию для хранилища секретных ключей предлагается название secring_bak.gpg). Именно с этой копией мы будем работать.


Не забудьте добавить к проекту консольного приложения BouncyCastle.Crypto.dll.



using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using Org.BouncyCastle.Bcpg.OpenPgp;


namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(
                "**Прочитаем файл с секретными ключами**\n");

            // путь до хранилища секретных ключей
            string path = @"secring_bak2.gpg";

            // прочитаем хранилище ключей
            Stream BundleStream = File.OpenRead(path);
            BundleStream =
                PgpUtilities.GetDecoderStream(BundleStream);

            PgpSecretKeyRingBundle pgpSec =
                new PgpSecretKeyRingBundle(BundleStream);

            // переберем все связки секретных ключей,
            // каждая связка содержит секретный и публичный ключи
            foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings())
            {
                // для каждого секретного ключа
                // покажем его уникальный идентификатор
                foreach (PgpSecretKey k in kRing.GetSecretKeys())
                {
                    Console.WriteLine(k.KeyId);
                }
            }

            BundleStream.Close();
            Console.ReadLine();
        }
    }
}Syhi-подсветка кода


Стоит отметить, что наше приложение выводит id ключей в десятеричной системе исчисления, а та же winPT в шестнадцатеричной. Вы можете проверить корректность вывода, скажем при помощи стандартного калькулятора windows – переведите число в нужную систему исчисления.


воскресенье, 7 октября 2007 г.

Подключение к MySQL C#.Net

Подключаться будем при помощи Open Database Connectivity (ODBC).


ODBC – это интерфейс благодаря которому приложение может получать доступ к различным базам данных.


По неизвестной причине поддержка MySQL не является предустановленной.
Однако сделать это самостоятельно совсем не сложно.



Для этого нужно скачать и установить MySQL Connector/ODBC 5.1


Ну вот, теперь посмотрим на код.



// добавим пространство имен
using System.Data.Odbc;Syhi-подсветка кода


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



private void button1_Click(object sender, System.EventArgs e)
{
// здесь обработчик события
}Syhi-подсветка кода


И так, вот этот «обработчик события»:



OdbcConnection MyConnection;

// составим строку подключения
string MyConString =
        "DRIVER={MySQL ODBC 5.1 Driver};" +
        "SERVER=test1.ru;" +
        "DATABASE=test_table;" +
        "UID=root;" +
        "PASSWORD=pass;" +
        "OPTION=3";

MyConnection = new OdbcConnection(MyConString);
MyConnection.ConnectionTimeout = 60;

// произведем попытку подключения
try
{
        MyConnection.Open();
}
catch(Exception ee)
{
        // если произошли ошибки покажем их
        MessageBox.Show (ee.ToString(),"Ошибка подключения к БД");
        return;
}Syhi-подсветка кода