|
Программирование >> Oracle
1668 Приложение А 6 / PL/SQL procedure successfully completed. Это позволяет не гадать, каким будет размер возвращаемых контрольных сумм. Для данных типа VARCHAR2 предлагается четыре функции CHECKSUM (включая типы DATE и NUMBER, для которых выполняется неявное преобразование), RAW, CLOB и BLOB. Следует помнить, что контрольная сумма по алгоритму MD5 будет в1числяться только по первым 32 Кбайтам данных типа CLOB или BLOB, поскольку с переменными большего размера в языке PL/SQL работать нельзя. Представленная далее реализация пакета не только дает более удобные в использовании средства шифрования, но и демонстрирует несколько полезных приемов. Во-первых, она показывает, как легко создать свою оболочку со специализированным интерфейсом для стандартных пакетов базы данных. В данном случае мы обходим ряд очевидных ограничений пакета DBMS OBFUSCATION TOOLKIT. Во-вторых, показан один из методов разработки пакета, защищенного от будущих изменений в реализации стандартных пакетов. Хотелось бы создать один пакет-оболочку, который бу работать в версиях 8.1.6 и 8.1.7 и обеспечивать при этом полный доступ к возможностям версии 8.1.7. Если бы для доступа к подпрограммам DESENCRYPT, DES3DECRYPT и средствам поддержки алгоритма MD5 использовался статический SQL, пришлось бы создавать отдельную версию пакета для версии 8.1.6 сервера, поскольку функций для алгоритмов MD5 и DES3 в версии 8.1.6 нет. Использованный в реализации динамический вызов позволяет создать пакет, который можно использовать в обеих версиях сервера. При этом также сокращается объем кода, который необходимо написать. Вот реализация пакета CRYPT PKG с описанием выполняемых действий. create or replace package body crypt pkg as - глобальные переменные пакета g charkey varchar2(48); g stringFunction varchar2(1); g rawFunction varchar2(1); g stringWhich varchar2(75); g rawWhich varchar2(75); g chunkSize CONSTANT number default 32 000; Пакет начинается с объявления глобальных переменных и констант. G CHARKEY. В ней хранится ключ типа RAW или VARCHAR2 для использования подпрограммами шифрования. Ее длина - 48 байт, чтобы можно было хранить 24-байтовый ключ типа RAW (при этом длина удваивается из-за преобразования в шестнадцатеричный вид данных типа RAW при записи в переменную типа VARCHAR2). G STRINGFUNCTION и G RAWFUNCTION. Содержит после вызова SETKEY пустое значение либо строку 3. Мы будем динамически добавлять эту строку к имени подпрограммы при выполнении, чтобы вызывать DESENCRYPT либо DES3ENCRYPT, в зависимости от размера ключа. Другими словами, она используется для формирования имени вызываемой функции. Пакет DBMS OBFUSCATION TOOLKIT 1669 G STRINGWHICH и G RAWWHICH. Используется только для функций DES3ENCRYPT/DES3DECRYPT. Добавляет четвертый необязательный параметр, требующий использования тройного ключа, когда алгоритм 3DES работает в этом режиме. Тогда как предыдущая строковая переменная определяет, какую из функций вызывать: DESENCRYPT или DES3ENCRYPT, эта переменная задает, какое значение должно быть передано для размера ключа: для двойного или тройного. GCHUNKSIZE. Константа, задающая размер фрагмента шифруемого/дешифруемого большого объекта. Она также задает максимальный размер данных, посылаемых функциям вычисления контрольной суммы по алгоритму MD5 при работе с большими объектами. Важно, чтобы это значение было кратно 8, - это предполагается в представленной далее реализации. Далее имеется шесть небольших служебных подпрограмм. Они являются вспомогательными и используются другими подпрограммами пакета: function padstr(p str in varchar2) return varchar2 as l len number default length(p str) ; begin returnto char(l len,fm00000009) rpad(p str, (trunc(l len/8)+sign(mod(l len,8)))*8, chr(0)); end; function padraw(p raw in raw) return raw l lennumberdefaultutl raw.length(p raw); begin return utl raw.concat(utl raw.cast to raw(to char(l len,fm00000009)), p raw, utl raw.cast to raw(rpad(chr(0), (8-mod(l len,8))*sign(mod(l len,8)), chr(0)))); end; При описании алгоритма шифрования DES было сказано, что DES шифрует данн1е блоками по 64 бита (8 байт). Значит, пакет DBMS OBFUSCATION TOOLKIT работает только с данными, длина которых кратна 8 байтам. Если шифруется строка длиной 7 байт, ее надо дополнить до 8. 9-байтовую строку необходимо дополнить до 16 байт. Две представленных выше подпрограммы кодируют и дополняют до нужной длины строки и данные типа RAW. Кодирование происходит путем помещения значения исходного размера данных перед данными в строку. Затем строка дополняется двоичными нулями (CHR(0)) до длины, кратной 8 байтам. Например, строка Hello World будет закодирована следующим образом: tkyte@TKYTE816>selectlength(padstr),padstr, dump(padstr) dump 2 from 3 (selectto char(l len,fm00000009) 4 zpad(p str, 5 (trunc(l len/8)+sign(mod(l len,8)))*8. 1670 Приложение А 6 chr(0)) padstr 7 from (select length(Hello World) l len, 8 Hello World p str 9 from dual 10 ) 11 ) 12 / LENGTH(PADSTR) PADSTR DUMP 24 00000011Hello World Typ=l Len=24: 48,48,48,48,48,4 8,49,49,72,101,108,108,111,32, 87,111,114,108,100,0,0,0,0,0 Окончательная длина закодированной строки - 24 байта (LENGTH(PADSDTR)), а исходная длина была 11 байт (это видно в первых восьми символах значения PADSTR). В столбце DUMP, где выданы десятичные значения байтов строки, можно увидеть, что строка завершается пятью двоичными нулями. Нам пришлось добавить 5 байт, чтобы дополнить 11-байтовую строку Hello World до длины, кратной 8. Далее идут подпрограммы, отменяющие выполненное выше дополнение нулевыми байтами: function unpadstr(p str in varchar2 ) return varchar2 is begin return substr(p str, 9, to number(substr(p str,l,8))); end; function unpadraw(p raw in raw) return raw is begin returnutl raw.substr(p raw, 9, to number(utl raw.cast to varchar2(utl raw.substr(p raw,1,8)))) ; end; Они достаточно понятны. Предполагается, что в первых восьми байтах строки или данных типа RAW находится исходная длина строки, и возвращается соответствующая подстрока закодированных данных. Осталось две вспомогательные процедуры: procedure wa(p clob in out clob, p buffer in varchar2) is begin dbms lob.writeappend(p clob, length(p buffer) , p buffer) ; end; procedure wa(p blob in out blob, p buffer in raw) is begin dbms lob.writeappend(p blob, utl raw.length(p buffer) , p buffer) ; end; Они упрощают вызов DBMS LOB.WRITEAPPEND, сокращая имя до двух букв (WA) и передавая длину записываемого фрагмента буфера - она всегда совпадает с полной длиной буфера.
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |