मुझे हमारे उत्पाद के डीएल को छोड़ने और इसे शुद्ध सी # एक के साथ बदलने का असाइनमेंट दिया गया है। पुराना डीएलएल एक .NET 2.0 प्रबंधित सी ++ (सी ++ \ सीएलआई) है जो Win32 देशी क्रिप्टो एपीआई को कॉल लपेटता है। नए डीएलएल को & विधियों के साथ एक नई वस्तु का खुलासा करना चाहिए, लेकिन सी # (.NET 4.0) के साथ लिखा जाना चाहिए। बेशक, नए डीएलएल को उसी तरह से एन्क्रिप्ट करना चाहिए (और डिक्रिप्ट) पुराने के रूप में - अन्यथा, एक सुरक्षित स्टोरेज में सभी सहेजे गए एन्क्रिप्टेड पासवर्ड जैसे डीबी या फ़ाइल में - हल नहीं किया जाएगा!Win32 Crypto API का अनुवाद सिस्टम # सुरक्षा के साथ सी # पर कॉल करता है। क्रिप्टोग्राफ़ी
इस (छद्म) देशी के कोड (Win32) API कॉल (ध्यान दें इनपुट alway यूनिकोड इनकोडिंग) है:
//buffer_to_encrypt - Is the input to the following procedure and is the buffer
// to be encrypted using 3DES and the below password to generate a valid 3DES key
// The buffer is Unicode encoded!!!
HCRYPTPROV m_provider = NULL;
HCRYPTHASH m_hash = NULL;
HCRYPTKEY m_key = NULL;
static const unsigned char password[] = {
0xF1, 0x49, 0x4C, 0xD0, 0xC1,
0xE2, 0x1A, 0xEA, 0xFB, 0x34,
0x25, 0x5A, 0x63, 0xA5, 0x29,
0x09, 0x8E, 0xB6, 0x7B, 0x75
}; //20 BYTES password
CryptAcquireContextW(&m_provider, NULL, NULL, PROV_DH_SCHANNEL, CRYPT_MACHINE_KEYSET | CRYPT_VERIFYCONTEXT);
CryptCreateHash(m_provider, CALG_SHA1, NULL, 0, &m_hash);
CryptHashData(m_hash, password, (DWORD)20, 0); //password is a 20Bytes buffer
CryptDeriveKey(m_provider, CALG_3DES, m_hash, CRYPT_EXPORTABLE, &m_key);
CryptEncrypt(m_key.handle(), NULL, TRUE, 0, buffer_to_encrypt, &dwFilled, (DWORD)total);
return buffer_to_encrypt;
अब, मैं सी # का उपयोग कर उसी प्रक्रिया लिखने के लिए कोशिश कर रहा हूँ (System.Security.Cryptography नाम स्थान) नेट एपीआई द्वारा उजागर नई क्रिप्टो वस्तुओं के साथ:
class Encryptor
{
private static byte[] password = {
0xF1, 0x49, 0x4C, 0xD0, 0xC1,
0xE2, 0x1A, 0xEA, 0xFB, 0x34,
0x25, 0x5A, 0x63, 0xA5, 0x29,
0x09, 0x8E, 0xB6, 0x7B, 0x75
}; //20 BYTES password, same as the above native code
private static byte[] EncryptInternal(string source)
{
byte[] resultArray = null;
byte[] streamToEncrypt = Encoding.Unicode.GetBytes(source);
using (TripleDESCryptoServiceProvider prov3des = new TripleDESCryptoServiceProvider())
{
prov3des.Mode = CipherMode.ECB;
prov3des.Padding = PaddingMode.PKCS7;
using (PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, null)) //No slat needed here
{
prov3des.Key = pdb.CryptDeriveKey("TripleDES", "SHA1", prov3des.KeySize, ZeroIV);
}
ICryptoTransform cTransform = prov3des.CreateEncryptor();
resultArray = cTransform.TransformFinalBlock(streamToEncrypt, 0, streamToEncrypt.Length);
}
return resultArray;
}
}
यहाँ मैं एक कष्टप्रद समस्या का सामना करना पड़ कर रहा हूँ - एन्क्रिप्टेड सरणी (एन्क्रिप्टेड बफर परिणाम) समान नहीं है दोनों तरीकों का उपयोग कर! प्रत्येक सरणी के पहले 8 बाइट्स (64 बिट्स) समान हैं, लेकिन अगले बाइट्स नहीं हैं। इससे छोटे स्ट्रिंग्स (अधिकतम 3 वर्ण) दोनों विधियों का उपयोग करके समान रूप से एन्क्रिप्ट किए जाते हैं, लेकिन लंबे तारों के परिणामस्वरूप विभिन्न एन्क्रिप्टेड डेटा होते हैं।
मैं दो विधियों को समकक्ष कैसे बना सकता हूं? यही है - & एन्क्रिप्ट करने के लिए उसी तरह से डिक्रिप्ट करें ताकि आउटपुट वही होगा? मुझे यहां क्या याद आ रही है? क्या .NET & मूल (Win32) API के बीच डिफ़ॉल्ट मान \ व्यवहार का कोई परिवर्तन है? (मुझे लगता है कि Win32 Crypto API में डिफ़ॉल्ट 3DES साइफर मोड ईबीसी है जबकि सी # सीबीसी का डिफ़ॉल्ट उपयोग - अगर मैं गलत हूं तो कृपया मुझे सही करें)।
धन्यवाद!
ओमरी
जोड़ने के लिए भूल कर रहे हैं), इसलिए मैंने माना कि वे .NET प्रक्रिया लिखते समय अनदेखा कर रहे हैं। * सी # विधि में 'शून्यव' चर एक 8 बाइट शून्य मूल्यवान सरणी है। – OmriSela
क्या आपने यह देखने के लिए जांच की है कि क्या पासवर्ड (पासवर्ड से प्राप्त बाइट्स) प्राप्त हो रहा है, दोनों कार्यान्वयन के लिए समान है? – pstrjds