का उपयोग कर आईफोन पर एन्क्रिप्टेड कुछ सी # में डिक्रिप्ट करने में समस्या होने के कारण मैंने इस पर दो दिन बिताए हैं और मेरे निपटारे में हर स्रोत के माध्यम से काम किया है, इसलिए यह अंतिम उपाय है।आरएसए
मेरे पास एक एक्स 50 9 प्रमाण पत्र है जिसका सार्वजनिक कुंजी मैंने आईफोन की कीचेन (केवल इस बिंदु पर सिम्युलेटर) में संग्रहीत किया है। एएसपी.नेट पक्ष पर, मुझे प्रमाण पत्र में एक निजी कुंजी के साथ प्रमाण पत्र मिला है। जब मैं आईफोन पर एक स्ट्रिंग एन्क्रिप्ट करता हूं और इसे सर्वर पर डिक्रिप्ट करता हूं, तो मुझे CryptographicException
"खराब डेटा" मिलता है। मैंने Array.Reverse
को RSACryptoServiceProvider
पृष्ठ में लंबे समय तक सुझाए गए प्रयासों की कोशिश की, लेकिन इससे मदद नहीं मिली।
मैंने दोनों तरफ बेस -64 स्ट्रिंग की तुलना की है और वे बराबर हैं। मैंने डीकोडिंग के बाद कच्चे बाइट एरे की तुलना की है और वे भी बराबर हैं। अगर मैं सार्वजनिक कुंजी का उपयोग कर सर्वर पर एन्क्रिप्ट करता हूं, तो बाइट सरणी आईफोन के संस्करण से अलग है और निजी कुंजी का उपयोग करके आसानी से डिक्रिप्ट करता है। कच्ची सादा पाठ स्ट्रिंग 115 वर्ण है, इसलिए यह मेरी 2048-बिट कुंजी की 256-बाइट सीमा के भीतर है।
यहाँ iPhone एन्क्रिप्शन विधि (काफी CryptoExercise sample app के wrapSymmetricKey
विधि से शब्दशः) है:
+ (NSData *)encrypt:(NSString *)plainText usingKey:(SecKeyRef)key error:(NSError **)err
{
size_t cipherBufferSize = SecKeyGetBlockSize(key);
uint8_t *cipherBuffer = NULL;
cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
memset((void *)cipherBuffer, 0x0, cipherBufferSize);
NSData *plainTextBytes = [plainText dataUsingEncoding:NSUTF8StringEncoding];
OSStatus status = SecKeyEncrypt(key, kSecPaddingNone,
(const uint8_t *)[plainTextBytes bytes],
[plainTextBytes length], cipherBuffer,
&cipherBufferSize);
if (status == noErr)
{
NSData *encryptedBytes = [[[NSData alloc]
initWithBytes:(const void *)cipherBuffer
length:cipherBufferSize] autorelease];
if (cipherBuffer)
{
free(cipherBuffer);
}
NSLog(@"Encrypted text (%d bytes): %@",
[encryptedBytes length], [encryptedBytes description]);
return encryptedBytes;
}
else
{
*err = [NSError errorWithDomain:@"errorDomain" code:status userInfo:nil];
NSLog(@"encrypt:usingKey: Error: %d", status);
return nil;
}
}
और यहाँ सर्वर साइड सी # डिक्रिप्शन विधि है:
private string Decrypt(string cipherText)
{
if (clientCert == null)
{
// Get certificate
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
foreach (var certificate in store.Certificates)
{
if (certificate.GetNameInfo(X509NameType.SimpleName, false) == CERT)
{
clientCert = certificate;
break;
}
}
}
using (var rsa = (RSACryptoServiceProvider)clientCert.PrivateKey)
{
try
{
var encryptedBytes = Convert.FromBase64String(cipherText);
var decryptedBytes = rsa.Decrypt(encryptedBytes, false);
var plaintext = Encoding.UTF8.GetString(decryptedBytes);
return plaintext;
}
catch (CryptographicException e)
{
throw(new ApplicationException("Unable to decrypt payload.", e));
}
}
}
मेरे संदेह है कि था प्लेटफार्मों के बीच कुछ एन्कोडिंग समस्याएं थीं।
मुझे पता है कि एक बड़ा एंडियन है और दूसरा छोटा-प्यारा है लेकिन मुझे यह जानने के लिए पर्याप्त नहीं पता कि कौन सा है या अंतर को कैसे दूर किया जाए।
मैक ओएस एक्स, विंडोज़, और आईफोन सभी छोटे-एंडियन हैं इसलिए समस्या नहीं है।
नया सिद्धांत: यदि आप ओएईपी पैडिंग बूलियन को झूठी पर सेट करते हैं, तो यह पीकेसीएस # 1 1.5 पैडिंग पर डिफ़ॉल्ट होता है।
जाहिर है, SecKey
में केवल
SecPadding
PKCS1
,
PKCS1MD2
,
PKCS1MD5
, और
PKCS1SHA1
की परिभाषाएं हैं। शायद माइक्रोसॉफ्ट के पीकेसीएस # 1 1.5! = ऐप्पल के पीकेसीएस 1 और इसलिए पैडिंग एन्क्रिप्शन के बाइनरी आउटपुट को प्रभावित कर रहा है। मैंने
kSecPaddingPKCS1
का उपयोग
fOAEP
false
पर सेट करने का प्रयास किया और यह अभी भी काम नहीं कर रहा है।
kSecPaddingPKCS1
equivalent पीकेसीएस # 1 1.5 के लिए है। सिद्धांतों और नरक पर ड्राइंग बोर्ड पर वापस;
अन्य नव कोशिश की सिद्धांत:
- प्रमाणपत्र iPhone (.cer फ़ाइल) पर वास्तव में PKCS सर्वर (.pfx फ़ाइल) और इसलिए यह काम नहीं कर सकता था पर # 12 बंडल के रूप में समान नहीं है। विभिन्न प्रमाणपत्र स्टोर में स्थापित .cer फ़ाइल और सर्वर-एन्क्रिप्टेड स्ट्रिंग राउंडट्रिप बस ठीक है; आधार -64
- रूपांतरण करने के लिए और सर्वर पर पोस्ट करने का कार्य विचित्रता में हुई है कि एक ही कक्षा गोल यात्रा में मौजूद तो मैं पहले कुछ URLEncoding/डिकोडिंग करने की कोशिश की और फिर iPhone से कच्चे बाइनरी पोस्ट सत्यापित है कि यह बराबर था, नहीं था और एक ही खराब डेटा मिला;
- मेरी मूल स्ट्रिंग 125 बाइट्स थी इसलिए मैंने सोचा कि यह यूटीएफ -8 (लंबे शॉट) में छंटनी हो सकती है, इसलिए मैंने इसे 44-बाइट स्ट्रिंग में बिना किसी परिणाम के फसल कर दिया;
- सिस्टम पर वापस देखा गया। क्रिप्टोग्राफी लाइब्रेरी यह सुनिश्चित करने के लिए कि मैं एक उचित वर्ग का उपयोग कर रहा हूं और 'आरएसएपीकेसीएस 1 केई एक्सचेंज डिफॉर्मेटर' की खोज की, नई संभावनाओं पर उत्साहित हो गया, और जब यह बिल्कुल वही व्यवहार करता था तो निराश हो गया।
सफलता!
यह पता चला कि आईफोन सिम्युलेटर पर मेरे कीचेन में कुछ क्रूर था जो पानी को हल कर रहा था, इसलिए बोलने के लिए। मैंने ~/Library/Application Support/iPhone Simulator/User/Library/Keychains/keychain-2-debug.db
पर कीचेन डीबी को फिर से बनाया जाने के कारण हटा दिया और यह ठीक काम किया। आपकी सारी मदद के लिए शुक्रिया। आंकड़े यह कुछ सरल लेकिन गैर स्पष्ट हो गया होता। (दो बातें मुझे पता चला: 1) सिम्युलेटर से एप्लिकेशन की स्थापना रद्द अपने कीचेन प्रविष्टियों स्पष्ट नहीं है और 2) समय-समय पर पूरी तरह से नई शुरुआत)
नोट:। कीचेन फ़ाइल के लिए जेनेरिक पथ iOS संस्करण पर निर्भर है: ~/Library/अनुप्रयोग समर्थन/iPhone सिम्युलेटर/[संस्करण] /Library/Keychains/keychain-2-debug.db जैसे, ~/Library/अनुप्रयोग समर्थन/iPhone सिम्युलेटर/4.3/Library/Keychains/कीचेन-2-डिबग .db
एक उपहार के लिए समय! – bbrown