2012-02-10 9 views
7

मैं डेल्फी 7 में डेटा को एन्क्रिप्ट और पोस्ट है, जहां मैं mcrypt साथ यह decrypting हूँ (के माध्यम से एक PHP स्क्रिप्ट को भेजने के लिए दिसम्बर 3.0 पुस्तकालय (Delphi Encryption Compedium Part I) का उपयोग करने के कोशिश कर रहा हूँ रिजेंडेल 5656, ईसीबी मोड)।डेल्फी दिसम्बर पुस्तकालय (क्रिप्ट) एन्क्रिप्शन

डेल्फी हिस्सा:

uses Windows, DECUtil, Cipher, Cipher1; 

function EncryptMsgData(MsgData, Key: string): string; 
var RCipher: TCipher_Rijndael; 
begin 
    RCipher:= TCipher_Rijndael.Create(KeyStr, nil); 
    RCipher.Mode:= cmECB; 
    Result:= RCipher.CodeString(MsgData, paEncode, fmtMIME64); 
    RCipher.Free; 
end; 

पीएचपी हिस्सा:

function decryptMsgContent($msgContent, $sKey) { 
    return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $sKey, base64_decode($msgContent), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)); 
} 

समस्या यह है कि PHP से डिक्रिप्शन काम नहीं करता है और उत्पादन, अस्पष्ट है वास्तविक डेटा से भिन्न।

बेशक, डेल्फी Key और PHP $Key वही 24 वर्ण स्ट्रिंग है।

अब मुझे पता है कि डीईसी 3.0 पुराना और पुराना है, और मैं एन्क्रिप्शन में एक विशेषज्ञ नहीं हूं और यह नहीं बता सकता कि कार्यान्वयन वास्तव में रिजेंडेल 256 है। शायद कोई मुझे बता सकता है कि यह कार्यान्वयन PHP के मैक्रिप्ट w/RIJNDAEL_256। शायद चाबियाँ अलग है, या ब्लॉक आकार है, लेकिन कोड से यह नहीं बता सकता है। मैं जानता हूँ कि ईसीबी मोड अनुशंसित नहीं है

और मैं जितनी जल्दी सीबीसी इस्तेमाल करेंगे के रूप में मैं ईसीबी काम कर पाने: यहाँ Cipher1.pas से एक अंश है:

const 
{ don’t change this } 
    Rijndael_Blocks = 4; 
    Rijndael_Rounds = 14; 

class procedure TCipher_Rijndael.GetContext(var ABufSize, AKeySize, AUserSize: Integer); 
begin 
    ABufSize := Rijndael_Blocks * 4; 
    AKeySize := 32; 
    AUserSize := (Rijndael_Rounds + 1) * Rijndael_Blocks * SizeOf(Integer) * 2; 
end; 

साइड सवाल। सवाल यह है कि, क्या मुझे जेनरेटेड चतुर्थ को डेल्फी में PHP स्क्रिप्ट में भी प्रेषित करना है? या कुंजी को जानना पर्याप्त है, ईसीबी की तरह?

+0

यह एक बहुत बेवकूफ सवाल हो सकता है। लेकिन डेल्फी का उपयोग करके आप अपने एन्क्रिप्टेड डेटा को डिक्रिप्ट कर सकते हैं? ओह, और इस प्रश्न का उत्तर मदद करता है: http://stackoverflow.com/q/8313992/41338 – RobS

+0

आप mcrypt_create_iv() को कॉल करते हैं। डेल्फी में आपने किस चौथाई का उपयोग किया था? –

+0

@ldsandon: टेलिएडर ईसीबी मोड का उपयोग कर रहा है। कोई चतुर्थ नहीं है। –

उत्तर

6

आप टीसीफर को कॉल कर रहे हैं। क्रिएट (कॉन्स पासवर्ड: स्ट्रिंग; एफ़्रेंस: टीप्रोन्चर); कन्स्ट्रक्टर, जो इनिट विधि को पास करने से पहले पासवर्ड के हैश की गणना करेगा, जो कार्यान्वित एल्गोरिदम के मानक कुंजी शेड्यूल करता है। इस कुंजी व्युत्पन्न को ओवरराइड करने के लिए, उपयोग करें:

function EncryptMsgData(MsgData, Key: string): string; 
var RCipher: TCipher_Rijndael; 
begin 
    RCipher:= TCipher_Rijndael.Create('', nil); 
    RCipher.Init(Pointer(Key)^,Length(Key),nil); 
    RCipher.Mode:= cmECB; 
    Result:= RCipher.CodeString(MsgData, paEncode, fmtMIME64); 
    RCipher.Free; 

अंत;

+0

धन्यवाद, यह मुझे सही रास्ते पर रखता है।मैं वास्तव में अपने पासवर्ड परिवर्तन का उपयोग कर रहा हूं (पोस्ट किए गए कोड से छोड़ा गया) जो पासवर्डसेक्रेट + टाइमस्टैम्प (जो पोस्ट डेटा के साथ जाता है) के sha1 के पहले 24 अक्षर लेता है। मुझे ऐसा करने के लिए बाध्य किया गया था जब मुझे PHP में कोई त्रुटि मिली कि mcrypt ने अधिकतम 24 वर्णों की कुंजी स्वीकार कर ली है। – talereader

+0

समस्या का दूसरा हिस्सा यह था कि डीईसी कार्यान्वयन वास्तव में ** 128 बिट्स ** रिजेंडेल है। पाया कि RIJNDAEL_128 का उपयोग करने के लिए PHP डिक्रिप्ट फ़ंक्शन को बदलकर। अब PHP डिक्रिप्शन फ़ंक्शन के आउटपुट में मूल डेटा + अंत में कुछ गड़बड़ है। स्टैक ओवरफ्लो पर पहले की पोस्ट में जो मैंने पहले पढ़ा है, उससे कहीं कहीं एक पैडिंग समस्या है जिसे मुझे पता लगाना है। – talereader

+0

इसके अलावा, डीईसी स्रोत को देखकर, इसे 128 बिट्स के ब्लॉक आकार और 256 (एईएस 256) के मुख्य आकार के रूप में बदलने के लिए कुछ संशोधन करना संभव होगा, इसलिए यह मैक्रिप्ट w/RIJNDAEL_256 के साथ जोड़ेगा ? – talereader

2

ठीक है, तो यह योग करने के लिए, वहाँ मेरी कोड के साथ 3 समस्या आई थी: mcrypt और सामान्य रूप में सिफर की मेरी गरीब समझ के कारण

  1. , MCRYPT_RIJNDAEL_256 128 बिट ब्लॉक और नहीं करता है 'को संदर्भित करता है चाबी का संदर्भ लें। मेरी सही पसंद MCRYPT_RIJNDAEL_128 होनी चाहिए, जो एईएस मानक है और डीईसी 3.0 द्वारा भी समर्थित है।

  2. डीईसी का अपना डिफ़ॉल्ट कुंजी व्युत्पन्न है, इसलिए मुझे इसे बाईपास करने की आवश्यकता है इसलिए मुझे इसे PHP में भी लागू नहीं करना पड़ेगा। वास्तविकता में, मैं अपने स्वयं के मुख्य व्युत्पन्न एल्गोरिदम का उपयोग कर रहा हूं जो PHP में पुन: उत्पन्न करना आसान था (sha1 (कुंजी) के पहले 32 वर्ण)।

  3. डीईसी साइफर के ब्लॉक आकार के एकाधिक में सादे टेक्स्ट नहीं करता है, क्योंकि मैक्रिप्ट अपेक्षा करता है, इसलिए मुझे इसे मैन्युअल रूप से करना पड़ा।

प्रदान काम कर नीचे कोड:

डेल्फी:

uses Windows, DECUtil, Cipher, Cipher1, CryptoAPI; 

function EncryptMsgData(MsgData, Key: string): string; 
var RCipher: TCipher_Rijndael; 
    KeyStr: string; 
begin 
    Result:= ''; 
    try 
    // key derivation; just making sure to feed the cipher a 24 chars key 
    HashStr(HASH_SHA1, Key, KeyStr); 
    KeyStr:= Copy(KeyStr, 1, 24); 
    RCipher:= TCipher_Rijndael.Create('', nil); 
    RCipher.Init(Pointer(KeyStr)^, Length(KeyStr), nil); 
    RCipher.Mode:= cmECB; 
    Result:= RCipher.CodeString(MsgData + StringOfChar(#0,16-(Length(MsgData) mod 16)), paEncode, fmtMIME64); 
    RCipher.Free; 
    except 
    end; 
end; 

पीएचपी:

function decryptMsgContent($msgContent, $sKey) { 
    $sKey = substr(sha1(sKey), 0, 24); 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $sKey, base64_decode($msgContent), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
} 
+0

उम। SHA-1 केवल 20 बाइट आउटपुट करेगा। सबसे आसान समाधान संभवत: 128 बिट्स/16 बाइट्स तक कुंजी आकार को कम करने के लिए है। एक और विकल्प एसएचए -256 का उपयोग करना और डीईसी 3.0 से दूसरी लाइब्रेरी में स्विच करना है जो SHA-256 का समर्थन करता है, जैसे OpenStrSecII या StreamSec Tools या डीसीपी क्रिप्ट। तीसरा विकल्प कुंजी खींचने के साथ SHA-1 का उपयोग करना है, लेकिन यह आसानी से PHP में लागू करने के लिए जटिल हो सकता है, और डीईसी 3.0 में पीकेसीएस # 5 v2.0 फ़ंक्शंस लागू नहीं किया गया है। –

+0

क्या मैं यह कहने में सही हूं कि ऊपर दिया गया कोड वास्तव में एईएस-128 का उपयोग करता है, और 1 9 2 नहीं, भले ही कुंजी लंबाई में 24 वर्ण है? क्या मुझे 16 की लंबाई कम होनी चाहिए? क्योंकि मैं इस समय के लिए एईएस-128 रहूंगा, यह एक छोटी परियोजना है। इसके अलावा, मैंने सीबीसी में स्विच किया, डीईसी को आंतरिक रूप से चौथाई उत्पन्न करने दें और मैं डेटा के साथ IV IV64ccoded पास करता हूं। – talereader

+0

यह एईएस -192 का उपयोग करता है, लेकिन कुंजी में अधिकतम 160 बिट्स (एसएचए -1 की आउटपुट लंबाई से घिरा हुआ) है, और कुंजी के अंतिम 4 बाइट (# 21 से # 24) अनिर्धारित हैं (हालांकि संभवतः 0 क्योंकि आप इसे काम कर रहे हैं)। –

0

एक 256 बिट कुंजी मैंने पाया 32 charachters, या 32 बाइट है। 24 नहीं। यह मुद्दा हो सकता है।

[संपादित करें]

मैं एक फिक्स के साथ एक ही विचार में हर किसी के विचारों (ansistring, आदि) संयुक्त।

इसके अलावा, आप codestring उपयोग कर रहे हैं (- यह Encodestring किया जाना चाहिए (

मैं काम कर नीचे एन्क्रिप्ट और डिक्रिप्ट स्रोत चिपकाया:


function EncryptMsgData(MsgData, Key: AnsiString): AnsiString; 
var RCipher: TCipher_Rijndael; 
begin 
    RCipher:= TCipher_Rijndael.Create('', nil); 
    RCipher.Init(Pointer(Key)^,Length(Key),nil); 
    RCipher.Mode:= cmCBC; 
    Result:= RCipher.EncodeString(MsgData); 
    RCipher.Free; 
end; 

function DecryptMsgData(MsgData, Key: AnsiString): AnsiString; 
var RCipher: TCipher_Rijndael; 
begin 
    RCipher:= TCipher_Rijndael.Create('',nil); 
    RCipher.Init(Pointer(Key)^,Length(Key),nil); 
    RCipher.Mode:= cmCBC; 
    Result:= RCipher.DecodeString(MsgData); 
    RCipher.Free; 
end; 

उपयोग है कि एक 32 चरित्र के साथ कुंजी और आपको उचित एन्क्रिप्शन और डिक्रिप्शन मिलते हैं।

एन्क्रिप्ट को स्टोर और उपयोग करने के लिए टेड डेटा एक स्ट्रिंग के रूप में आप बेस 64Encode (

का उपयोग करना चाह सकते हैं लेकिन डिक्रिप्टिंग से पहले बेस 64Decode को न भूलें।

ब्लोफिश के लिए यह वही तकनीक है। कभी-कभी charachters वास्तव में बैकस्पेस की तरह हैं, और स्क्रीन पर दिखाने के बजाय समारोह प्रदर्शन करते हैं। Base64Encode मूल रूप से charachters को उस पाठ में परिवर्तित करता है जिसे आप टेक्स्ट में प्रदर्शित कर सकते हैं।

एक ही या किसी अन्य भाषा में इंटरनेट भर में या किसी अन्य अनुप्रयोग के लिए इनकोडिंग डेटा स्थानांतरित करने से पहले, आप नहीं ढीला आंकड़ों के base64encode और क्रम में डिकोड करना आवश्यक है। PHP में भी इसे मत भूलना!

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