در اوراکل 10gR1، پسورد کاربران استفاده شده برای dblink، بدون رمزنگاری و بصورت کاملا شفاف(clear text) در جداول data dictionary ذخیره می شدند و امکان مشاهده کلمه عبور به صورت clear text، از طریق ویوهای data dictionary امکان پذیر بود:
SQL*Plus: Release 10.1.0.4.2 – Production on Wed Apr 18 11:23:01 2018
SQL> create database link dblinkname connect to usef identified by “pass@123” using ‘tns_name’;
Database link created.
SQL> select DB_LINK,USERNAME,PASSWORD from USER_DB_LINKS;
DB_LINK USERNAME PASSWORD
——————– ———- ———-
DBLINKNAME USEF pass@123
از اوراکل 10gR2، دیگر این پسورد به صورت clear text در جدول $link ذخیره نمی شود و شکل غیرشفاف و مبهم آن در فیلد passwordx قابل مشاهده می باشد:
SQL*Plus: Release 10.2.0.4.0 – Production on Wed Apr 18 11:47:43 2018
SQL> select NAME,USERID,PASSWORDx from link$ where NAME=’DBLINKNAME’;
DBLINKNAME USEF 058912ACD56360CE56C3603FCB4254FF4F684965E1F1A1BB02
با نگهداری پسورد به این فرم، چالش اساسی نسخه قبلی در این زمینه از بین رفته است ولی کماکان می توان با کمک بسته dbms_crypto، پسوردهای مربوط به این دسته از کاربران را از حالت مبهم خارج کرد. این کار از نسخه 10gR2 تا نسخه 11.2.0.1 قابل انجام است:
SQL*Plus: Release 11.2.0.1.0 Production on Sun Apr 22 14:43:08 2018
SQL> select name, userid, utl_raw.cast_to_varchar2(dbms_crypto.decrypt((substr(passwordx,19)), 4353, (substr(passwordx,3,16)))) password from sys.link$ where name =upper(‘dblinkname’);
NAME USERID PASSWORD
———- ———- ———-
DBLINKNAME USEF pass@123
در صورت ارتقا بانک اطلاعاتی به نسخه های بالاتر از 11.2.0.1، رمزگشایی (با کمک بسته dbms_crypto) برای رمزهای قدیمی امکان پذیر می باشد منتها برای dblinkهای جدید، این قابلیت از بین خواهد رفت.
با این حال، یک جستجوی ساده اینترنتی می تواند در این زمینه راهگشا باشد!
با دانلود یک اسکریپت و با ایجاد یک پروسیجر(متن پروسیجر)، خواهیم توانست حتی در اوراکل 18c هم شکل clear text پسورد این دسته از کاربران را مشخص کنیم. این کاربا کمک فیلد $value از جدول $props و همچنین passwordx از جدول $link قایل انجام خواهد بود:
SQL> create database link dblink_18c connect to usef identified by ramz_karbar_usef using ‘noncdb’;
Database link created
SQL> SELECT VALUE$ FROM SYS.PROPS$ WHERE name = ‘NO_USERID_VERIFIER_SALT’;
D5F9A360515BCD63E0F11BB7A0C9C932
SQL> select PASSWORDX from link$ where NAME=’DBLINK_18C’;
PASSWORDX
——————————————————————————–
07852D3915D3B2A84A3AC6317035670B1C84FEE6253540FFC9998FB0688EEBFA055B01B336E66776
1207171D306C3273AF252DC7883D9ECA0AB5BA526875CF874F6069D44925EF7AE53ADA94A59E3D15
26B9DEA6F7EA4E6D00811051DC8C4DF5CEEF021D1630A468EA7ECE0AC486F62B66388EA73071DACEF0EC79D08592C24
مقدار passwordx و $value را به عنوان ورودی پروسیجر db_link_password_decrypt تعیین خواهیم کرد:
SQL> begin
db_link_password_decrypt(‘D5F9A360515BCD63E0F11BB7A0C9C932′,’07852D3915D3B2A84A3AC6317035670B1C84FEE6253540FFC9998FB0688EEBFA055B01B336E667761207171D306C3273AF252DC7883D9ECA0AB5BA526875CF874F6069D44925EF7AE53ADA94A59E3D1526B9DEA6F7EA4E6D00811051DC8C4DF5CEEF021D1630A468EA7ECE0AC486F62B66388EA73071DACEF0EC79D08592C246’);
end;
/
در خروجی این دستور، پسورد کاربر usef را خواهیم دید:
———-Decrypting DB Link password————–
Initialization_vector :
01000003000000000101000102000001
—————————————————
Ciphertext :
526875CF4F6949257AE53A9415EA4E81CEEFEA7E0AC486F62B8E30DAF0ECC246
—————————————————
Encryption key part 1 :
3915D33AC63170350B84FE25FFC999B068B336E612171D3073AF25C7880AB5BA
Encryption key part 2 :
5951DC807C0860807C927032C0E58CC691322228B2199AF559D054E3773D00AF
—————————————————
Encryption key (Part 1 XOR Part 2) :
60440FBABA3910B577168E173F2C1576F98114CEA00E87C52A7F7124FF37B515
—————————————————
Decrypted string: ramz_karbar_usef
Decrypted string: 1072616D7A5F6B61726261725F7573656691C50099037D2D23402DA599B65EEE
در ادامه این سیر تکاملی، قابلیت جدیدی در اوراکل 18c ارائه شد که از طریق ان می توان پسورد را به صورت دستی و با کمک دستور ALTER DATABASE DICTIONARY رمزنگاری(encrypt) کرد در ادامه مختصرا این ویژگی را شرح خواهیم داد.
ویژگی DICTIONARY CREDENTIALS ENCRYPT
بر اساس این ویژگی، ستونهای حاوی credential(همانند پسورد کاربران) که در جداول data dictionary نظیر $link و SCHEDULER$_CREDENTIAL ذخیره می شوند، به صورت دستی رمزنگاری خواهند شد و پس از ان، هرگونه استفاده از database link منوط به در دسترس بودن keystore می باشد.
نکته: keystore یا wallet فایلی است که کلید اصلی کنونی و گذشته بانک در ان قرار خواهد گرفت و در صورت حذف این فایل، اطلاعات رمزنگاری شده، قابل استفاده نخواهند بود.
در ادامه بطور مختصر به بررسی چگونگی استفاده از این ویژگی و همچنین نحوه اثرگذاری ان در استفاده از database link خواهیم پرداخت.
توجه: قبل از فعال کردن این ویژگی، dblinkای با نام dblink_18c ایجاد شده که متن فیلد پسورد ان را در قسمت زیر می بینید:
SQL> select PASSWORDX from link$ where NAME=’DBLINK_18C’;
PASSWORDX
——————————————————————————–
07852D3915D3B2A84A3AC6317035670B1C84FEE6253540FFC9998FB0688EEBFA055B01B336E66776
1207171D306C3273AF252DC7883D9ECA0AB5BA526875CF874F6069D44925EF7AE53ADA94A59E3D15
26B9DEA6F7EA4E6D00811051DC8C4DF5CEEF021D1630A468EA7ECE0AC486F62B66388EA73071DACEF0EC79D08592C24
برای استفاده از این ویژگی(DICTIONARY CREDENTIALS ENCRYPT)، در ابتدا باید از وجود keystore در بانک اطلاعاتی مطمئن بود برای مشاهده وضعیت فعلی keystore، می توان به ویوی V$ENCRYPTION_WALLET رجوع کرد. در صورت عدم وجود keystore، با اتصال به بانک(با مجور syskm)، اقدام به ایجاد keystore کرده و پس از باز نمودن ان، ENCRYPTION KEY را برای این فایل تنظیم می کنیم:
SQL> conn usef/a as syskm
Connected.
ایجاد keystore:
SQL> ADMINISTER KEY MANAGEMENT CREATE KEYSTORE ‘/18c/base/admin/prim/wallet’ IDENTIFIED BY “pass_usef”;
keystore altered.
باز کردن keystore:
SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY “pass_usef”;
keystore altered.
تنظیم ENCRYPTION KEY:
SQL> ADMINISTER KEY MANAGEMENT SET ENCRYPTION KEY IDENTIFIED BY “pass_usef” WITH BACKUP;
keystore altered.
پس از انجام این مراحل، با کمک دستور ALTER DATABASE DICTIONARY، اطلاعات مورد نظر را در حالت encrypt قرار می دهیم:
SQL> ALTER DATABASE DICTIONARY ENCRYPT CREDENTIALS;
Database dictionary altered.
با اجرای این دستور، ابتدا پسوردهای جدول $link، از فرم مبهم خارج شده و به حالت ابتدایی(clear text) برخواهند گشت و سرانجام رمزنگاری خواهند شد.
نکته: برای مشاهده وضعیت فعلی این ویژگی، می توان از دستور زیر استفاده کرد:
SQL> select * from DICTIONARY_CREDENTIALS_ENCRYPT ;
ENABLED
بعد از فعال شدن این ویژگی، در صورت رجوع مجدد به جدول $link، شاهد تغییر مقدار فیلد passwordx برای DBLINK_18Cخواهیم بود(قسمت ابتدایی این مقدار را مشاهده می کنید):
SQL> select PASSWORDX from link$ where NAME=’DBLINK_18C’;
08EBEBFD4F6863CD0C9FD901AEAE262379932809476E15F51F60EE137E4A96BF6B45EA9EAB1C129FFA528DEB7B1F698B38C3257D5CA930ED4E9BDD9FBC12FA142C53366055BF738076AD531295AB2D7B0918C146C999CEF4A87F2C6212854CBC48DAB61F1526D2E6F137E99B0653E1633DD485C384EBDBA7F8899A81CA1EAB29
همچنین استفاده از پروسیجر قبلی، در این مورد جواب نخواهد داد:
SQL> begin
db_link_password_decrypt(‘D5F9A360515BCD63E0F11BB7A0C9C932′,’08EBEBFD4F6863CD0C9FD901AEAE262379932809476E15F51F60EE137E4A96BF6B45EA9EAB1C129FFA528DEB7B1F698B38C3257D5CA930ED4E9BDD9FBC12FA142C53366055BF738076AD531295AB2D7B0918C146C999CEF4A87F2C6212854CBC48DAB61F1526D2E6F137E99B0653E1633DD485C384EBDBA7F8899A81CA1EAB29’);
end;
/
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at “SYS.UTL_RAW”, line 380
ORA-06512: at “SYS.DB_LINK_PASSWORD_DECRYPT”, line 84
ORA-06512: at line 2
از این پس، برای هرگونه استفاده از dblink، باید فایل keystore در وضعیت open قرار داشته باشد:
SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE CLOSE IDENTIFIED BY “pass_usef”;
keystore altered.
SQL> select sysdate from dual@dblink_18c;
ORA-28365: wallet is not open
برای غیرفعال کردن این ویژگی، می توان از دستور زیر استفاده کرد:
SQL> ALTER DATABASE DICTIONARY DELETE CREDENTIALS key;
Database dictionary altered.
پ.ن: در صورت فعال بودن این ویژگی، در زمان اجرای دستور expdp/impdp، پیام زیر مشاهده خواهد شد که باید پس از اتمام عملیات import، پسورد مربوط به این کاربر را تغییر داد:
Processing object type SCHEMA_EXPORT/DB_LINK
ORA-39395: Warning: object USEF.dblink_18c requires password reset after import