Програмування.
PGPsdk
Вітаю вас, шановні читачі!Ця стаття буде корисна, якщо вам знадобилося використовувати у своїй програмі шифрування даних.
У статті буде розглянуто бібліотека PGPsdk. Вона реалізує функції шифрування і аутентифікації, управління ключами(створення, додавання до кільця), роботи з сервером відкритих ключів, генерації випадкових чисел. В бібліотеці реалізовані наступні алгоритми шифрування і хешування:
IDEA, 3DES, RSA, DSA, MD5, SHA.
Існують також версії бібліотеки під Windows і Mac OS.
Необхідне зауваження.
Автор не ставив перед збій завдання докладного розгляду даної роботи бібліотеки, він хоче тільки ознайомити читача з тим, які можливості вона надає програмісту. Додаткову інформацію дивіться у розділі «Посилання».Де дістати?
Архів з бібліотекою PGPsdk та документацією до неї можна знайти на сайті програми PGP http://www.pgpi.org.Заодно наведу пряме посилання на ftp-сервер ftp://ftp.hacktic.nl/pub/crypto/pgp/pgpsdk/”- Внутрішньо! — прошелестів дідок. — Внутрішньо дивіться, де у нееанализатор і думатель…”
Аркадій і Борис Стругацький. Казка про трійку

Що всередині?
В архіві знаходяться такі підкаталоги:
/docs
/headers
/libraries/static/
/test
у каталозі doc містяться два дуже важливих файлу:
PGPsdkUsersGuide.pdf містить базову інформацію по використанню бибилотеки (з прикладами)
PGPsdkReferenceGuide.pdf описує функції бібліотеки
директорія headers містить розробницькі файли glx
і нарешті /libraries/static/ містять файли архівів бібліотеки, в двох подкаталогахdebug і release:
libPGPsdkNetwork.a
libPGPsdk.a
При використанні PGPsdk спочатку необхідно ініціалізувати бібліотеку, це робиться функцією
PGPError PGPsdkInit( void );
Далі, при ініціалізації необхідно викликати функцію
PGPError PGPNewContext(PGPUInt32 clientAPIVersion, // kPGPsdkAPIVersion
PGPContextRef *pgpContext ); //покажчик на pgp-контекст
Ця функція створює новий pgp-контекст — необхідний параметр всіх функцій бібліотеки.

При завершенні роботи необхідно звільнити бібліотеки для цього необхідно спочатку звільнити всі використовувані ресурси (функціями PGPFreeFileSpec, PGPFreeFilter, PGPFreeKeySet, etc.), головне треба звільнити pgp-контекст, функцією
PGPError PGPFreeContext( PGPContextRef pgpContext );
після цього можна освождать бібліотеку
PGPError PGPsdkCleanup( void );

За кодом помилки, що повертається в змінну типу PGPError, можна отримати короткий опис помилки, з допомогою
PGPError PGPGetErrorString(PGPError theErrorCode, // код помилки
PGPsize availLength, // розмір буфера
char *theErrorText ); // покажчик на буфер для тексту повідомлення про помилку

Шифрування і електронний підпис здійснюється функцією
PGPError PGPEncode(PGPContextRef pgpContext,PGPOptionListRef firstOption,…,PGPOLastOption() );
А розшифровка
PGPError PGPDecode(PGPContextRef pgpContext,PGPOptionListRef firstOption,…,PGPOLastOption() );
Жуки
Було помічено, що при роботі з кільцем ключів через функцію
PGPError PGPOpenKeyRing ( context, kPGPKeyRingOpenFlags_Mutable, keyring, &KeyRing );
в каталозі створюються файли pubring-bak-1.pkr,pubring-bak-2.pkr і т. д. Якщо працювати .asc файлами ( ключі міститися у вигляді ASCII ), то проблем не виникає.

Я скачував кілька версій sdk, а так само исходники, але натикався на наступну проблему:
В документації функція перевірки пароля для ключа описана наступним чином:
PGPBoolean PGPPassphraseIsValid ( PGPKeySetRefkey, const char *passphrase );
, а у файлі pgpKeys.h
PGPBoolean PGPPassphraseIsValid ( PGPKeyDBObjRef key, PGPOptionListRef firstOption,… );
схоже, що треба використовувати так:
PGPBoolean PGPPassphraseIsValid( theKey,PGPOPassphrase( context, passphrase),PGPOLastOption( context ));
Посилання
Інших матеріалів по роботі з бібліотекою дуже мало, рекомендую подивитися статті Олексія Кірюшкіна на http://www.rsdn.ru/, в яких автор розглядає роботу з необхідними фуцкциями бібліотеки, а так само інкапсулює можливості бібліотеки PGPsdk в клас.Висновок
При компіляції перед опцією підключення архіву libPGPsdk.a необхідно підключити математичну бібліотеку(опцією -lm), т. к. PGPsdk використовує звідти деякі функції.
Хороші приклади використання можна знайти в документації до sdk, звідти взято приклад шифрування файлу наведений в урізанні. Як бачите, все дуже просто!Щасливо! noonv[AT]narod[.]ru
XIII / * ==== Encrypt a File code fragment ========================== *//** Demonstrates simple file encryption with the PGPsdk.** Encrypts file «C: estPlainText» with key [email protected],* producing encrypted file «C: estEncrypted».** — * More precisely:** The userID key has to be available in the default keyring;* for simplicity, this example uses a key with the user ID* [email protected]’.** Overwrites any existing output file with the same name.* — *//* Specify the key, input file name, and output filename to use */const char *userID = [email protected];const char *inFileName = «C: estPlainText»;const char *outFileName = «C: estEncrypted»;/* Declare and initialize variables */PGPError err = kPGPError_NoErr;PGPContextRef context = kInvalidPGPContextRef;PGPKeySetRef defaultKeyRing = kInvalidPGPKeySetRef;PGPFilterRef filter = kInvalidPGPFilterRef;PGPKeySetRef foundUserKeys = kInvalidPGPKeySetRef;PGPFileSpecRef inFileRef = kInvalidPGPFileSpecRef;PGPFileSpecRef outFileRef = kInvalidPGPFileSpecRef;/* — PGP Setup — *//* NOTE: These calls appear here for clarity only.* In a real-world application, you would call PGPsdkInit()* and PGPNewContext() at application startup time, not on* an operation-by-operation basis.*//* Initialize the PGPsdk libs */err = PGPsdkInit();if( IsPGPError( err ) ) goto Exit;/* Create the PGPContext */err = PGPNewContext( kPGPsdkAPIVersion, &context );if( IsPGPError( err ) ) goto Exit;/* — Prepare Encryption Operation Parameters — *//* Open the default keyring */err = PGPOpenDefaultKeyRings( context, kPGPKeyRingOpenFlags_Mutable,&defaultKeyRing );if( IsPGPError( err ) ) goto Exit;/* Create a filter to look for the default [email protected] key */err = PGPNewUserIDStringFilter( context, userID,kPGPMatchSubString, &filter );if( IsPGPError( err ) ) goto Exit;/* Look for the key */err = PGPFilterKeySet( defaultKeyRing, filter, &foundUserKeys );if( IsPGPError( err ) ) goto Exit;/* Create the file description */err = PGPNewFileSpecFromFullPath( context, inFileName, &inFileRef );if( IsPGPError( err ) ) goto Exit;err = PGPNewFileSpecFromFullPath( context, outFileName, &outFileRef );if( IsPGPError( err ) ) goto Exit;/* — Perform the Encryption operation — *//* This is the main event; everything above and* below exists only to support this call.** Produces the encrypted output file in the default directory.*/err = PGPEncode( context, PGPOEncryptToKeySet( context, foundUserKeys ), PGPOInputFile( context, inFileRef ), PGPOOutputFile( context, outFileRef ), PGPOLastOption( context ) );Exit:/* — Release resources used in this operation — */if( PGPFileSpecRefIsValid( inFileRef ) ) PGPFreeFileSpec( inFileRef );if( PGPFileSpecRefIsValid( outFileRef ) ) PGPFreeFileSpec( outFileRef );if( PGPFilterRefIsValid( filter ) ) PGPFreeFilter( filter );if( PGPKeySetRefIsValid( foundUserKeys ) ) PGPFreeKeySet( foundUserKeys );if( PGPKeySetRefIsValid( defaultKeyRing ) ) PGPFreeKeySet( defaultKeyRing );/* — PGP Shutdown — *//* NOTE: These calls appear here for clarity only.* In a real-world application, you would make these calls to* PGPFreeContext() and PGPsdkInit() at application shutdown time,* and not on an operation-by-operation basis.*//* Release the PGP context we’ve been using */if( PGPContextRefIsValid( context ) ) PGPFreeContext( context );/* PGP library shutdown */PGPsdkCleanup();/* ========== End of Encrypt a File code fragment ========== */