2011-09-01 5 views
7

मुझे ओरेकल डेटाबेस और एक MySQL डेटाबेस के बीच डेटा की तुलना करने की आवश्यकता है।ओरेकल और MySQL में एईएस एन्क्रिप्शन अलग-अलग परिणाम दे रहे हैं

ओरेकल में, डेटा को पहले AES-128 एल्गोरिदम के साथ एन्क्रिप्ट किया गया है, और फिर धोया गया है। जिसका अर्थ है कि डेटा को पुनर्प्राप्त करना और इसे डिक्रिप्ट करना संभव नहीं है।

वही डेटा MySQL में और सादा पाठ में उपलब्ध है। तो डेटा की तुलना करने के लिए, मैंने ओरेकल में किए गए चरणों का पालन करते समय एन्क्रिप्टिंग करने और फिर MySQL डेटा को हश करने की कोशिश की।

बहुत सारी कोशिशों के बाद, मुझे अंत में पता चला कि MySQL में aes_encrypt ओरेकल में से एक के मुकाबले अलग-अलग परिणाम देता है।

-- ORACLE: 
-- First the key is hashed with md5 to make it a 128bit key: 
raw_key := DBMS_CRYPTO.Hash (UTL_I18N.STRING_TO_RAW ('test_key', 'AL32UTF8'), DBMS_CRYPTO.HASH_MD5); 

-- Initialize the encrypted result 
encryption_type:= DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5; 

-- Then the data is being encrypted with AES: 
encrypted_result := DBMS_CRYPTO.ENCRYPT(UTL_I18N.STRING_TO_RAW('test-data', 'AL32UTF8'), encryption_type, raw_key); 

ओरेकल कोड के लिए परिणाम होगा: 8FCA326C25C8908446D28884394F2E22

-- MySQL 
-- While doing the same with MySQL, I have tried the following: 
SELECT hex(aes_encrypt('test-data', MD5('test_key')); 

MySQL कोड के लिए परिणाम होगा: DC7ACAC07F04BBE0ECEC6B6934CF79FE

मैं कुछ याद आ रही है? या अलग-अलग भाषाओं के बीच एन्क्रिप्शन विधियां समान नहीं हैं?

अद्यतन: नीचे टिप्पणी के अनुसार, मेरा मानना ​​है कि मैं इस तथ्य है कि Oracle में DBMS_CRYPTO.Hash का परिणाम MySQL में MD5 समारोह से लौट आए परिणाम के रूप में एक ही है उल्लेख करना चाहिए। हैं: के बाद से चतुर्थ कार्य करने के लिए पारित किया जा रहा है, इस प्रकार चतुर्थ के डिफ़ॉल्ट मान NULL

इनाम प्रयोग किया जाता है

इसके अलावा CBC या Oracle में CBE का उपयोग कर, एक ही परिणाम देता है किसी ने मेरी अंतिम टिप्पणी है, और तथ्य यह है कि अगर दोनों पक्षों पर एक ही गद्दी का उपयोग कर, एक ही परिणाम हो जाता है इनाम निकलेगा सत्यापित कर सकते हैं:

@rossum MySQL में डिफ़ॉल्ट गद्दी PKCS7, mmm है ... ओह .. ओरेकल में यह पीके का उपयोग कर रहा है सीएस 5, विश्वास नहीं कर सकता मैंने इसे नोटिस नहीं किया। धन्यवाद। (Btw ओरेकल PAD_PKCS7 विकल्प नहीं है, नहीं 11g में कम से कम)

+0

पहली नज़र में मुझे समस्या होने पर संदेह है: 'test_key', 'AL32UTF8' 'मेथिंक MySQL के पास आपके डेटा पर एक अलग वर्णमाला है और इस प्रकार एन्क्रिप्शन लागू होने से पहले अलग-अलग डेटा है। – Johan

+0

मुझे संदेह है कि एन्क्रिप्शन एक जैसा होना चाहिए, इसलिए मैं सुनिश्चित करता हूं कि चाबियाँ समान हों। यानी एमडी 5 हेक्स स्ट्रिंग या कच्चे बाइट्स लौटाता है। यदि हेक्स, मामले के बारे में क्या? दुर्भाग्य से मेरे पास OBcle तक DBMS_CRYPTO इंस्टॉल नहीं है। – Sodved

+0

@ कोडेड हां एमडी 5 हैशिंग उन दोनों डेटाबेसों में एक ही परिणाम दे रहा है जो '8C32D1183251DF9828F929B935AE0419' है। और चूंकि यह मामला @ जोहान है, इसलिए यह एन्कोडिंग समस्या नहीं होनी चाहिए क्योंकि एमडी 5 हैशिंग एक ही – Dan

उत्तर

8

MySQL के MD5 समारोह 32 हेक्साडेसिमल वर्णों की स्ट्रिंग रिटर्न कहते हैं। इसे बाइनरी स्ट्रिंग के रूप में चिह्नित किया गया है लेकिन यह 16 बाइट बाइनरी डेटा नहीं है जो उम्मीद करेगा।

तो यह तय करने के लिए, इस स्ट्रिंग वापस बाइनरी डेटा के लिए परिवर्तित किया जाना चाहिए:

SELECT hex(aes_encrypt('test-data', unhex(MD5('test_key')))); 

परिणाम है:

8FCA326C25C8908446D28884394F2E22 

यह फिर से 32 हेक्साडेसिमल वर्णों की स्ट्रिंग है। लेकिन अन्यथा यह ओरेकल के समान परिणाम है।

और btw:

  • MySQL PKCS7 गद्दी उपयोग करता है।
  • पीकेसीएस 5 पैडिंग और पीकेसीएस 7 पैडिंग एक और एक हैं। तो ओरेकल पैडिंग विकल्प सही है।
  • MySQL ईसीबी ब्लॉक सिफर मोड का उपयोग करता है। तो आपको तदनुसार कोड को अनुकूलित करना होगा। (यह पहले 16 बाइट्स के लिए कोई फर्क नहीं पड़ता है।)
  • MySQL कोई प्रारंभिक वेक्टर (आपके ओरेकल कोड के समान नहीं) का उपयोग करता है।
  • MySQL एक गैर-मानक फोल्डिंग कुंजी का उपयोग करता है। तो MySQL और Oracle (या .NET या Java) में एक ही परिणाम प्राप्त करने के लिए, केवल 16 बाइट लंबे कुंजी का उपयोग करें।
0

सीबीसी ईसीबी बनाम हो सकता है। इस पृष्ठ के तल पर टिप्पणी: http://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html mysql फ़ंक्शन का उपयोग करता ईसीबी

+0

मैंने उस टिप्पणी को देखा है और मैंने ओरेकल में ईसीबी को यह देखने के लिए कोशिश की है कि यह एक अलग परिणाम देता है, लेकिन ऐसा नहीं था। वास्तव में, अपेक्षित परिणाम है क्योंकि ईसीबी और सीबीसी मूल रूप से वही हैं यदि IV को एन्क्रिप्ट फ़ंक्शन पर नहीं भेजा गया था। (यह डिफ़ॉल्ट मान 'NULL' है) – Dan

+0

@Dan: वे केवल वही हैं यदि एकल ब्लॉक एन्क्रिप्ट किया जा रहा है। पैडिंग के साथ, पैडिंग के कारण वास्तव में एक ही ब्लॉक (16 बाइट्स) के रूप में शुरू किया गया था जो दो ब्लॉक तक बढ़ सकता है। – rossum

1

बस @ कोडो के बहुत ही व्यावहारिक उत्तर के आधार पर डमी के लिए पूरा समाधान देना चाहते हैं।

संपादित करें: सामान्य मामलों में सही किया जा रहा है के लिए, मैं इस पाया: - "PKCS # 5 गद्दी 8 बाइट ब्लॉक आकार के लिए PKCS # 7 गद्दी का एक सबसेट है।" तो कड़ाई से पीकेसीएस 5 एईएस पर लागू नहीं किया जा सकता है; उनका मतलब है पीकेसीएस 7 लेकिन उनके नामों का एक दूसरे से उपयोग करें।

About PKCS5 and PKCS7

/* MySQL एक गैर मानक एक महत्वपूर्ण तह उपयोग करता है। * तो MySQL और Oracle (या .NET या Java) में एक ही परिणाम प्राप्त करने के लिए, केवल 16 बाइट्स लंबा (32 हेक्साडेसिमल प्रतीकों) = 128 बिट्स एईएस एन्क्रिप्शन, MySQL AES_encrypt डिफ़ॉल्ट एक का उपयोग करें। * * इसका मतलब है कि MySQL 128 बिट्स एईएस एन्क्रिप्शन के लिए 16 और 32 बाइट्स के बीच किसी भी महत्वपूर्ण लंबाई को स्वीकार करता है, लेकिन गैर-16 बाइट कुंजी का उपयोग करने के लिए मानक एईएस द्वारा इसकी अनुमति नहीं है, इसलिए इसे ' टी 0 बाइट्स से अधिक के साथ कुंजियों के लिए अन्य प्लेटफॉर्म में मानक एईएस डिक्रिप्ट का उपयोग करने के लिए सक्षम करने के लिए सक्षम होगा, और XOR सामान, आदि के साथ उस अन्य प्लेटफॉर्म में की MySQL फोल्डिंग प्रोग्राम करने के लिए बाध्य होगा। पहले से ही बाहर है लेकिन क्यों अजीब गैर मानक चीजें कर रहे हैं बदल सकता है जब MySQL निर्णय, आदि)। ### ओरेकल - इसके अलावा, मैं वे कहते हैं कि एल्गोरिथ्म उन मामलों के लिए MySQL द्वारा चुना एक सुरक्षा स्तर पर एक बहुत बुरा चुनें है ... */

लगता है:

- पहले कुंजी md5 यह एक 128 बिट कुंजी बनाने के लिए साथ मिश्रित होता है (16 बाइट्स, 32 हेक्स प्रतीक):

raw_key := DBMS_CRYPTO.Hash (UTL_I18N.STRING_TO_RAW ('test_key', 'AL32UTF8'), DBMS_CRYPTO.HASH_MD5); 

- MySQL, AL32UTF8 का उपयोग करता है कम से कम डिफ़ॉल्ट

द्वारा - एन्क्रिप्शन मानकों कॉन्फ़िगर करें:

encryption_type:= DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_PKCS5; 

- कड़ाई से बोलते हुए, यह वास्तव में पीकेसीएस 7 है।

/* और मैं अगर आवेदन किया है और @Codo ने कहा कि यह सही है, लेकिन के रूप में मानक (Oracle) AES128 केवल 16 बाइट्स कुंजी को स्वीकार करेंगे, सीबीसी भी काम करता है, के रूप में मेरा मानना ​​है कि वे नहीं हैं तेजी से होने के लिए ईसीबी चुनें एक 16 बाइट कुंजी पर लागू किया। क्या कोई इसकी पुष्टि कर सकता है?बाइनरी (varbinary, ब्लॉब) परिणाम है -

encrypted_result := DBMS_CRYPTO.ENCRYPT(UTL_I18N.STRING_TO_RAW('test-data', 'AL32UTF8'), encryption_type, raw_key); 

: - */

फिर डेटा एईएस के साथ एन्क्रिप्टेड है।

- यदि आप हेक्स वर्णों में इसका प्रतिनिधित्व करना चाहते हैं तो कोई भी RAWTOHEX() का उपयोग कर सकता है। ओरेकल डिक्रिप्शन -

raw_key := HEXTORAW(32_hex_key) 
encryption_type := 6 + 768 + 4096 -- (same as above in numbers; see Oracle Docum.) 
raw_data := UTL_I18N.STRING_TO_RAW('test-data', 'AL32UTF8') 

encrypted_result := DBMS_CRYPTO.ENCRYPT(raw_data, encryption_type, raw_key) 

:

मामले में आप सीधे 16 बाइट्स हेक्स पात्रों प्रतिनिधित्व या 32 हेक्स यादृच्छिक वर्ण में पदबंध टुकड़ों में बांटा का उपयोग

decrypted_result := UTL_I18N.RAW_TO_CHAR(CRYPTO.DECRYPT(raw_data, encryption_type, raw_key), 'AL32UTF8') 

- एसक्यूएल में:

SELECT 
    UTL_I18N.RAW_TO_CHAR( 
    DBMS_CRYPTO.DECRYPT( 
    UTL_I18N.STRING_TO_RAW('test-data', 'AL32UTF8'), 
    6 + 768 + 4096, 
    HEXTORAW(32_hex_key) 
) , 'AL32UTF8') as "decrypted" 
FROM DUAL; 

- ### MySQL डिक्रिप्शन:

- MySQL का MD5 फ़ंक्शन 32 हेक्साडेसिमल वर्णों की एक स्ट्रिंग देता है (= 16 बाइट्स = 128 बिट्स)।

- इसे बाइनरी स्ट्रिंग के रूप में चिह्नित किया गया है लेकिन यह 16 बाइट बाइनरी डेटा नहीं है जो उम्मीद करेगा।

- नोट: ध्यान दें कि MD5, SHA1, आदि कार्यों की वापसी 5.3.x के बाद से कुछ संस्करणों में बदल गई है। MySQL 5.7 मैनुअल देखें।

- तो यह तय करने के लिए, इस स्ट्रिंग वापस हेक्स से बाइनरी डेटा के लिए unHex() के साथ परिवर्तित किया जाना चाहिए:

SELECT hex(aes_encrypt('test-data', unhex(MD5('test_key'))); 

पुनश्च: मैं MySQL 5.7 मैनुअल में बेहतर व्याख्या पढ़ना की सिफारिश करेंगे, जो इसके अलावा अब बहुत अधिक विन्यास की अनुमति देता है। MySQL AES_ENCRYPT improved explanation from v5.7 manual

संबंधित मुद्दे