Показаны сообщения с ярлыком C# .Net openPGP. Показать все сообщения
Показаны сообщения с ярлыком C# .Net openPGP. Показать все сообщения

среда, 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-подсветка кода


суббота, 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 – переведите число в нужную систему исчисления.