2008-09-18 3 views
5

के साथ openssl एन्क्रिप्शन का उपयोग करना मेरे पास एक विरासत सी ++ मॉड्यूल है जो openssl लाइब्रेरी (डीईएस एन्क्रिप्शन) का उपयोग करके एन्क्रिप्शन/डिक्रिप्शन प्रदान करता है। मैं जावा में है कि कोड का अनुवाद करने में कोशिश कर रहा हूँ, और मैं एक DLL, JNI, आदि ... सी ++ कोड की तरह दिखता है पर भरोसा नहीं करना चाहती:जावा

:

des_string_to_key(reinterpret_cast<const char *>(key1), &initkey); 
des_string_to_key(reinterpret_cast<const char *>(key2), &key); 
key_sched(&key, ks); 
// ... 
des_ncbc_encrypt(reinterpret_cast<const unsigned char *>(tmp.c_str()), 
reinterpret_cast< unsigned char *>(encrypted_buffer), tmp.length(), ks, &initkey, 
DES_ENCRYPT); 

return base64(reinterpret_cast<const unsigned char *>(encrypted_buffer), strlen(encrypted_buffer)); 

जावा कोड की तरह दिखता है

Cipher ecipher; 
try { 
    ecipher = Cipher.getInstance("DES"); 
    SecretKeySpec keySpec = new SecretKeySpec(key, "DES");  
    ecipher.init(Cipher.ENCRYPT_MODE, keySpec);   
    byte[] utf8 = password.getBytes("UTF8"); 
    byte[] enc = ecipher.doFinal(utf8); 
    return new sun.misc.BASE64Encoder().encode(enc); 
} 
catch { 
    // ... 
} 

तो मैं जावा में आसानी से डीईएस एन्क्रिप्शन कर सकता हूं, लेकिन उपर्युक्त कोड के साथ पूरी तरह अलग तरीके से मुझे एक ही परिणाम कैसे मिल सकता है? विशेष रूप से मुझे परेशान करने वाला यह तथ्य है कि सी ++ संस्करण 2 कुंजी का उपयोग करता है जबकि जावा संस्करण केवल 1 कुंजी का उपयोग करता है। सीबीसी मोड में डीईएस के बारे में उत्तर काफी संतोषजनक है लेकिन मैं इसे अभी तक काम नहीं कर सकता। यहां मूल कोड के बारे में अधिक जानकारी दी गई है: हस्ताक्षरित चार कुंजी 1 [10] = {0}; हस्ताक्षरित चार कुंजी 2 [50] = {0};

int i; 
for (i=0;i<8;i++) 
    key1[i] = 31+int((i*sqrt((double)i*5)))%100; 
key1[9]=0; 

for (i=0;i<48;i++) 
    key2[i] = 31+int((i*i*sqrt((double)i*2)))%100; 
key2[49]=0; 
... 
// Initialize encrypted buffer 
memset(encrypted_buffer, 0, sizeof(encrypted_buffer)); 

// Add begin Text and End Text to the encrypted message 
std::string input; 
const char beginText = 2; 
const char endText = 3; 
input.append(1,beginText); 
input.append(bufferToEncrypt); 
input.append(1,endText);  

// Add padding 
tmp.assign(desPad(input)); 

des_ncbc_encrypt(reinterpret_cast<const unsigned char *>(tmp.c_str()),  
reinterpret_cast< unsigned char *>(encrypted_buffer), tmp.length(), ks, &initkey, 
DES_ENCRYPT); 
... 

से मैं क्या पढ़ा है, कुंजी 56 होना चाहिए (या 64, यह मेरे लिए स्पष्ट नहीं है) लंबे बिट्स, लेकिन यहाँ यह 48 बाइट्स लंबा है।

+0

यह बताने के लिए पर्याप्त कोड नहीं है कि बाद में key1 और key2 का उपयोग किस प्रकार किया जाता है ... – Alexander

उत्तर

1

मैं ओपनएसएसएल विशेषज्ञ नहीं हूं, लेकिन मुझे लगता है कि सी ++ कोड सीबीसी मोड में डीईएस का उपयोग कर रहा है, इस प्रकार एक चतुर्थ की आवश्यकता है (यही वह है जो initKey शायद है, और यही कारण है कि आपको लगता है कि आपको दो चाबियाँ चाहिए)। यदि मैं सही हूं, तो आपको अपने जावा कोड को सीबीसी मोड में डीईएस का उपयोग करने के लिए भी बदलना होगा, फिर जावा कोड को एन्क्रिप्शन कुंजी और IV की आवश्यकता होगी।

0

एल्गोरिदम मेल खाना चाहिए; यदि आपको अलग-अलग परिणाम मिल रहे हैं तो आपको चाबियाँ और टेक्स्ट को संभालने के तरीके से निपटना पड़ सकता है। यह भी ध्यान रखें कि जावा वर्ण 2 बाइट लंबा हैं, जो सी ++ वर्ण 1 बाइट हैं, इसलिए इसका कुछ संबंध हो सकता है।

1

इसके अलावा, ध्यान रखें कि आपको वास्तव में सूर्य का उपयोग नहीं करना चाहिए। * आपके कोड में कक्षाएं। यह अन्य वीएम में तोड़ सकता है क्योंकि ये सार्वजनिक एपीआई नहीं हैं। अपाचे कॉमन्स कोडेक्स (दूसरों के बीच) में बेस 64 के कार्यान्वयन हैं जो इस समस्या को सहन नहीं करते हैं।

मुझे सच में यकीन नहीं है कि एकल डीईएस कभी भी कई चाबियों का उपयोग क्यों करेगा। भले ही आप ट्रिपल-डीईएस का उपयोग कर रहे हों, मुझे विश्वास है कि आप जावा क्रिप्टोग्राफी एपीआई के साथ अलग-अलग कुंजियों का उपयोग करने के बजाय एक कुंजी (डेटा के अधिक बाइट्स के साथ) का उपयोग करेंगे।