4.14. Внешняя библиотека ЭЦП

Библиотека btkCryptDll используется для работы с ЭЦП посредством WinAPI библиотеки WinCrypt2.

4.14.1. Использование

Библиотека позволяет генерировать пары асимметричных ключей, формировать ЭЦП для произвольного текста с помощью закрытого ключа, а также верифицировать подписи с помощью открытого ключа.

4.14.2. Загрузка библиотеки

Note

В версии Oracle 9i это обычно каталог C:\\oracle\\ora92\\bin\\, в версии Oracle 10g это обычно C:\\oracle\\product\\10.2.0\\db_1\BIN.

Файл библиотеки находится в SVN по адресу:

  • 32 bit: //svn/depot/Application/CryptLibrary/DLL/btkCryptDll.dll
  • 64 bit: //svn/depot/Application/CryptLibrary/DLL/btkCryptDll64.dll

4.14.3. Изменения listener.ora

В файле listener.ora необходимо добавить строки:

(SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = C:\oracle\product\10.2.0\db_1)
      (PROGRAM = extproc)
      (ENV = "EXTPROC_DLLS=ANY")
    )

(SID_DESC =

      (GLOBAL_DBNAME = GLOBAL)
      (ORACLE_HOME = C:\oracle\product\10.2.0\db_1)
      (SID_NAME = GLOBAL)
      (ENV = "EXTPROC_DLLS=ANY")
    )

и LISTENER =

(DESCRIPTION_LIST =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
    (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
  )
)

4.14.4. Изменения Tnsnames.ora

В файл tnsnames.ora необходимо добавить следующие строки для подключения внешних процедур:

EXTPROC_CONNECTION_DATA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
    )
    (CONNECT_DATA = (SID = PLSExtProc) (PRESENTATION = RO) )
  )

Причем необходимо отметить что значение KEY (в данном примере это EXTPROC) должно соответствовать значению параметра KEY из строки (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC)) файла listener.ora, а значение SID (в данном примере это PLSExtProc) должно соответствовать значению SID_NAME из строки (SID_NAME = PLSExtProc) файла listener.ora.

После изменения файлов необходимо перезапустить службу TNSListener.

4.14.5. Подключение библиотеки

Для подключения библиотеки необходимо выполнить скрипт:

CREATE OR REPLACE library btkcriptlib
  AS 'C:\oracle\product\10.2.0\db_1\BIN\btkCryptDll.dll';

Attention

Путь к библиотечной DLL должен быть полный и регистрозависимый!

4.14.5.1. Прототипы функций

Функция генерации ключей:
FUNCTION GetCryptoKeys(rawPubKey OUT RAW, rawPrvKey OUT RAW)

    RETURN PLS_INTEGER AS
    LANGUAGE C
    LIBRARY btkcriptlib NAME "GetRSAKeys"
    parameters(rawPubKey RAW
              ,rawPubKey LENGTH
              ,rawPrvKey RAW
              ,rawPrvKey LENGTH);

Возвращаемые значения: в случае успеха 1, в противном случае 0.

Параметры:

  • rawPubKey – публичный ключ,
  • rawPrvKey – закрытый ключ.
Функция формирования подписи
FUNCTION  SignMsg(spMsg IN VARCHAR2, rawPrvKey IN RAW, rawSign OUT RAW)

   RETURN PLS_INTEGER AS
   LANGUAGE C
   LIBRARY tstlib NAME "SignMessage"
   parameters(spMsg     string
             ,spMsg     LENGTH
             ,rawPrvKey RAW
             ,rawPrvKey LENGTH
             ,rawSign   RAW
             ,rawSign   LENGTH);

Возвращаемые значения: в случае успеха 1, в противном случае 0.

Параметры:

  • spMsg – подписываемый текст,
  • rawPrvKey – закрытый ключ,
  • rawSign – подпись.
Функция верификации подписи
FUNCTION VerifyMsg(spMsg IN VARCHAR2, rawPubKey IN RAW, rawSign IN RAW)

   RETURN PLS_INTEGER AS
   LANGUAGE C
   LIBRARY tstlib NAME "VerifyMessage"
   parameters(spMsg     string
             ,spMsg     LENGTH
             ,rawPubKey RAW
             ,rawPubKey LENGTH
             ,rawSign   RAW
             ,rawSign   LENGTH);

Возвращаемые значения: в случае успеха 1, в случае неверной подписи -1, в случае внутренней ошибки 0.

Параметры:

  • spMsg – проверяемый текст,
  • rawPrvKey – открытый ключ,
  • rawSign – подпись.

4.14.5.2. Тестовый пример

В данном примере все четыре результата должны быть равны 1 (единице).

DECLARE
  pub RAW(2000);
  prv RAW(2000);
  pub2 RAW(2000);
  prv2 RAW(2000);
  sgn RAW(2000);
BEGIN
  :res := BTK_Crypt2.GetCryptoKeys(pub, prv);
  :res4 := BTK_Crypt2.GetCryptoKeys(pub2, prv2);
  :res2 := BTK_Crypt2.SignMsg('Hello World!', prv, sgn);
  :res3 := BTK_Crypt2.VerifyMsg('Hello World!', pub, sgn);
END;

Если изменить пример так чтобы проверить подпись другим открытым ключом, то в параметре :res3 мы должны получить -1.

DECLARE
  pub RAW(2000);
  prv RAW(2000);
  pub2 RAW(2000);
  prv2 RAW(2000);
  sgn RAW(2000);
BEGIN
  :res := BTK_Crypt2.GetCryptoKeys(pub, prv);
  :res4 := BTK_Crypt2.GetCryptoKeys(pub2, prv2);
  :res2 := BTK_Crypt2.SignMsg('Hello World!', prv, sgn);
  :res3 := BTK_Crypt2.VerifyMsg('Hello World!', pub2, sgn);
END;