2017-06-08 15 views
5

मैं वर्तमान में एक वर्ग है कि यादृच्छिक रूप से जनरेट एन्क्रिप्शन एक स्मार्ट कार्ड से एक X509 प्रमाण पत्र से एन्क्रिप्टेड कुंजी के साथ पाठ की बड़ी मात्रा को एन्क्रिप्ट पर काम कर रहा हूँ, एक RSACryptoServiceProvider का उपयोग कर स्वामी कुंजी प्रदर्शन करने के लिए एन्क्रिप्शन और डिक्रिप्शन ऑपरेशन। हालांकि, जब मेरे पास foEAP पैडिंग विकल्प सत्य पर सेट किया गया है, तो मेरे पास हर बार डिक्रिप्शन पर त्रुटि "ओएईपी पैडिंग डीकोड करते समय त्रुटि" होती है। मैंने कुंजी आकार की जांच की है और यह स्वीकार्य सीमाओं के भीतर है। और मैं यह सुनिश्चित करने के लिए ब्रेकपॉइंट्स से गुज़र चुका हूं कि एन्क्रिप्शन फ़ंक्शन से वापस आने वाली बेस 64 स्ट्रिंग एन्क्रिप्टेड बेस 64 स्ट्रिंग के समान सटीक है जो फ़ाइल को फिर से लोड होने पर डिक्रिप्शन फ़ंक्शन पर वापस भेज दिया जाता है।सी #: त्रुटि जबकि डिकोडिंग OAEP गद्दी अजीब मुद्दा

कुंजी जोड़ी निश्चित रूप से सही है, क्योंकि यह ओएईपी के बिना ठीक काम करती है। और मैंने टेक्स्ट एन्कोडिंग भी जांच ली है।

संपादित करें: यह पता चला है कि यह एक स्मार्ट कार्ड विशिष्ट मुद्दा हो सकता है, जब मैंने स्थानीय X509 प्रमाण पत्र के साथ डिक्रिप्शन करने का प्रयास किया तो डिक्रिप्शन सफल हुआ।

संपादित करें:

string TestString = "Hello World!"; 
X509Certificate2 cert = DRXEncrypter.GetCertificate("Select a test certificate", "Select a certificate to use for this test from the local store."); 
string key = DRXEncrypter.GenerateEncryptionKey(214); 
Console.WriteLine("Encryption Key: " + key); 

string encrypted = DRXEncrypter.EncryptBody(TestString, key); 
Console.WriteLine("Encrypted Body: " + encrypted); 

string cryptokey = DRXEncrypter.EncryptWithCert(cert, key); 
Console.WriteLine("Encrypted Decryption Key: " + cryptokey); 

string decrypted = DRXEncrypter.DecryptBody(encrypted, cryptokey, cert); 
Console.WriteLine("Decrypted Body: " + decrypted); 

Console.WriteLine("Output String: " + decrypted + "."); 

यहाँ क्रिप्टो प्रदाता वर्ग मैं लिखा है से कोड है: यह डिक्रिप्शन कोड है कि विफल रहता है। मैं इस मुद्दे पर घंटों तक फंस गया हूं, इसलिए अगर कोई मेरी मदद कर सकता है तो यह बहुत अच्छा होगा।

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Security.Cryptography; 
using System.Security.Cryptography.X509Certificates; 
using System.IO; 

namespace CoreDRXEditor 
{ 
public class DRXEncrypter 
{ 
    private byte[] Salt = Encoding.ASCII.GetBytes("81PO9j8I1a94j"); 
    private string EncryptionKey; 
    private const bool UseOAEP = true; 

    public DRXEncrypter(string EncryptionKey) 
    { 
     this.EncryptionKey = EncryptionKey; 
    } 

    public static string EncryptBody(string body, string encryptionkey) 
    { 
     // Use the plaintext master key to encrypt the body. 
     DRXEncrypter enc = new DRXEncrypter(encryptionkey); 

     // Encrypt the body. 
     return enc.Encrypt(body); 
    } 

    public static int GetMaxKeySize(X509Certificate2 cert) 
    { 
     RSACryptoServiceProvider csp = cert.PublicKey.Key as RSACryptoServiceProvider; 

     return csp.KeySize; 
    } 

    public static string DecryptBody(string body, string encryptionkey, X509Certificate2 cert) 
    { 
     // Decrypt the encrypted encryption key with the certificate. 
     string DecryptedKey = Convert.ToBase64String(DecryptWithCert(cert, encryptionkey)); 

     // Create a new DRXEncrypter using the decrypted encryption key to decrypt the body. 
     DRXEncrypter enc = new DRXEncrypter(DecryptedKey); 

     // Return the decrypted body. 
     return enc.Decrypt(body); 
    } 

    public static string GenerateEncryptionKey(int KeyLength) 
    { 
     using (RandomNumberGenerator rng = new RNGCryptoServiceProvider()) 
     { 
      byte[] CryptoBytes = new byte[KeyLength]; 
      rng.GetBytes(CryptoBytes); 

      return Convert.ToBase64String(CryptoBytes); 
     } 
    } 

    public static X509Certificate2 GetCertificate(string title, string message) 
    { 
     X509Store cstore = new X509Store(StoreLocation.CurrentUser); 
     cstore.Open(OpenFlags.ReadOnly); 

     X509CertificateCollection certs = X509Certificate2UI.SelectFromCollection(cstore.Certificates, title, message, X509SelectionFlag.SingleSelection); 

     if (certs.Count == 1) 
     { 
      X509Certificate2 mcert = certs[0] as X509Certificate2; 
      return mcert; 
     } 
     else 
     { 
      return null; 
     } 
    } 

    public static string EncryptWithCert(X509Certificate2 cert, string PlainText) 
    { 
     RSACryptoServiceProvider csp = cert.PublicKey.Key as RSACryptoServiceProvider; 

     byte[] PlainBytes = Convert.FromBase64String(PlainText); 

     // This converts the plain text into a byte array and then encrypts the raw bytes. 
     byte[] CryptoBytes = csp.Encrypt(PlainBytes, UseOAEP); 

     // This converts the encrypted bytes into a Base64 string. 
     string ReturnString = Convert.ToBase64String(CryptoBytes); 

     return ReturnString; 
    } 

    public static byte[] DecryptWithCert(X509Certificate2 cert, string EncryptedText) 
    { 
     RSACryptoServiceProvider csp = cert.PrivateKey as RSACryptoServiceProvider; 

     //CspParameters csps = new CspParameters(); 

     byte[] EncryptedBytes = Convert.FromBase64String(EncryptedText); 

     // This converts the encrypted, Base64 encoded byte array from EncryptWithCert() to a byte[] and decrypts it. 
     byte[] CryptoBytes = csp.Decrypt(EncryptedBytes, UseOAEP); 

     return CryptoBytes; 
    } 

    public string Encrypt(string PlainText) 
    { 
     RijndaelManaged Algorithm = null; 
     string Output = null; 

     try 
     { 
      Rfc2898DeriveBytes PrivateKey = new Rfc2898DeriveBytes(this.EncryptionKey, this.Salt); 


      Algorithm = new RijndaelManaged(); 
      Algorithm.Key = PrivateKey.GetBytes(Algorithm.KeySize/8); 
      Algorithm.Padding = PaddingMode.PKCS7; 

      ICryptoTransform Encryption = Algorithm.CreateEncryptor(Algorithm.Key, Algorithm.IV); 

      using (MemoryStream msa = new MemoryStream()) 
      { 
       msa.Write(BitConverter.GetBytes(Algorithm.IV.Length), 0, sizeof(int)); 
       msa.Write(Algorithm.IV, 0, Algorithm.IV.Length); 
       using (CryptoStream csa = new CryptoStream(msa, Encryption, CryptoStreamMode.Write)) 
       { 
        using (StreamWriter swa = new StreamWriter(csa)) 
        { 
         swa.Write(PlainText); 
        } 
       } 
       Output = Convert.ToBase64String(msa.ToArray()); 
      } 
     } 
     finally 
     { 
      if (Algorithm != null) 
      { 
       Algorithm.Clear(); 
      } 
     } 

     return Output; 
    } 

    public string Decrypt(string EncryptedText) 
    { 
     RijndaelManaged Algorithm = null; 
     string Output = null; 

     try 
     { 
      Rfc2898DeriveBytes PrivateKey = new Rfc2898DeriveBytes(this.EncryptionKey, this.Salt); 

      byte[] KeyBytes = Convert.FromBase64String(EncryptedText); 
      using (MemoryStream msb = new MemoryStream(KeyBytes)) 
      { 
       Algorithm = new RijndaelManaged(); 
       Algorithm.Key = PrivateKey.GetBytes(Algorithm.KeySize/8); 
       Algorithm.IV = ReadByteArray(msb); 
       Algorithm.Padding = PaddingMode.PKCS7; 
       ICryptoTransform Decryption = Algorithm.CreateDecryptor(Algorithm.Key, Algorithm.IV); 
       using (CryptoStream csb = new CryptoStream(msb, Decryption, CryptoStreamMode.Read)) 
       { 
        using (StreamReader srb = new StreamReader(csb)) 
        { 
         Output = srb.ReadToEnd(); 
        } 
       } 

      } 
     } 
     finally 
     { 
      if (Algorithm != null) 
      { 
       Algorithm.Clear(); 
      } 
     } 

     return Output; 
    } 

    public static string Sha512(string ToHash) 
    { 
     using (SHA512 SHA = new SHA512Managed()) 
     { 
      byte[] HashByte = Encoding.UTF8.GetBytes(ToHash); 
      byte[] HashBytes = SHA.ComputeHash(HashByte); 
      string Hash = System.Text.Encoding.UTF8.GetString(HashBytes, 0, HashBytes.Length); 
      return Hash; 
     } 
    } 

    public static string Base64Encode(string data) 
    { 
     byte[] str = Encoding.UTF8.GetBytes(data); 
     return Convert.ToBase64String(str); 
    } 

    public static string Base64Decode(string data) 
    { 
     byte[] str = Convert.FromBase64String(data); 
     return Encoding.UTF8.GetString(str); 
    } 

    private byte[] ReadByteArray(Stream st) 
    { 
     byte[] Length = new byte[sizeof(int)]; 
     st.Read(Length, 0, Length.Length); 
     byte[] Buffer = new byte[BitConverter.ToInt32(Length, 0)]; 
     st.Read(Buffer, 0, Buffer.Length); 

     return Buffer; 
    } 
} 
} 
+0

आपकी एन्क्रिप्शनिंग स्ट्रिंग क्या एन्कोडिंग है? –

+2

यह भी देखें [क्रिप्टोग्राफिक टोकन उद्योग के लिए एक बुरे जोड़े) [https://blog.cryptographyengineering.com/2012/06/21/bad-couple-of-years-for-cryptographic/)। क्या आप निश्चित हैं कि यह पीकेसीएस पैडिंग नहीं है? – jww

+1

दाई बोक: यह बेस 64 है। GenerateEncryptionKey() फ़ंक्शन देखें। – CitadelCore

उत्तर

0

सुनिश्चित करें कि आपके कुंजी का आकार बहुत छोटा या बहुत बड़ी नहीं है सुनिश्चित करें।

से MSDN

टिप्पणियां देखें RSACryptoServiceProvider 8 बिट की वृद्धि के साथ 16384 बिट्स 384 बिट्स से कुंजी के आकार का समर्थन करता है यदि आप Microsoft बढ़ी क्रिप्टोग्राफिक प्रदाता इंस्टॉल नहीं है। यदि आपके पास माइक्रोसॉफ्ट बेस क्रिप्टोग्राफिक प्रदाता स्थापित है तो यह 8 बिट्स की वृद्धि में 384 बिट्स से 512 बिट्स के प्रमुख आकारों का समर्थन करता है।

तो तुम पैड करने के लिए कुछ बाइट्स के साथ कम कुंजी तार आवश्यकता हो सकती है कम से कम कुंजी लंबाई

+0

जब मैं इसे आज़माता हूं तो मुझे "अनचाहे अपवाद: सिस्टम.Security.Cryptography.CryptographicException: खराब लंबाई" मिलती है। स्मार्ट कार्ड का प्रमाण पत्र केवल 2048-बिट एन्क्रिप्शन तक समर्थन करता है। (256 बाइट अधिकतम है।) – CitadelCore

+0

इसके अलावा, प्रदाता "माइक्रोसॉफ्ट एन्हांस्ड आरएसए और एईएस क्रिप्टोग्राफिक प्रदाता" है। – CitadelCore

0

ठीक प्राप्त करने के लिए, मैं इस जांच करने के लिए और प्रबंधित मैं क्या देख सकते हैं, मैं कुछ प्रमाण पत्र में समस्याएं आ रही हैं। मुझे यकीन नहीं है कि कुछ प्रमाण पत्र क्यों काम करते हैं जबकि अन्य नहीं करते हैं। यह जानना अच्छा होगा कि इस मामले में कुछ प्रमाणपत्र क्यों विफल हो गए?

वैसे भी, मैंने विंडोज़ "फ़ाइल एन्क्रिप्शन प्रमाणपत्र प्रबंधित करें" का उपयोग करके एक नया स्वयं हस्ताक्षरित प्रमाणपत्र बनाया और इस प्रमाणपत्र का उपयोग किया, और सभी काम करने लगते हैं।

आपके कोड से बाहर रखा गया।

Encryption Key: aUc/GXWDoh2LktaEGeCJfju1dHP118yD/fzfT0iJLuhOq2QeyGpG6m3aBHaxvdH0ufeXRHbMjmlmPgIL/bhABzkT2C5Oa6ZhY3IFXb5t7JXZ3AtUunvtNAnRyFJ7MzklrSZGgQ 
vF67DSNfIVE17doKt6j6mkCpSco56ooZCrOs2Mp3vSXqNjvjiwMEfQbk41aYUNVNVNlBGhdNQCIZIAKezQCUpWqzn2II27FIDfqDIEW4ieyzpXC05GzUlGXDxFOiFUPk3n0Y94vgeF8AlCD74eyZtz 
WQ== 
Encrypted Body: EAAAANS/W7+GGRbT1q5NCYvZlDZYtxaA8g55HzUqP5qxhenn 
Encrypted Decryption Key: vc/tcsApmY1503BFi7oSu/RDvZivA1Ed58KJuLoEC6eE8q0BIa6ye2JvtXyxkVbzzL0MA51pZ2ZhMIsfCnBsEDjCgy+JLTZTGM1Mv+em9frFUKb0zHbICnPUa/3H 
yd1yOWsdn5ws19QN2dzC6eau+ExhT2T/vyZO4Nf9NdHKnB8n2yB1rrQ/T+N2EYCNH/AVPDAsme6JG7k9Od2XIipBXMyCgXgWYZmQusq+JQjA9d3c4CrQYcg/ERF+K3oZv/gPicBkAR5taxwSxAajGg 
bpkJNsbhTMHTN9bOn333qZ6ojlo5e882baZXuZWPr9qtj1b7ONoOyuSx/OvGKjt93BQg== 
Decrypted Body: Hello World! 
Output String: Hello World!. 

आशा है कि मदद करता है

+0

हाँ, मुझे पता है कि मशीन प्रमाण पत्र काम करते हैं, यह सिर्फ मेरे स्मार्ट कार्ड पर प्रमाण पत्र है जो काम करने में विफल रहता है। मैंने अलग-अलग ईकेयू के साथ एक ही स्मार्ट कार्ड पर अन्य प्रमाणपत्रों के साथ प्रयास किया है। – CitadelCore

+0

क्या आपके पास उस प्रमाणपत्र के लिए निजी कुंजी है? –

+0

हां, जैसा कि मैंने पहले उल्लेख किया था ओएईपी पैडिंग एकमात्र चीज है जो डिक्रिप्शन को काम करने से रोकती है। डिक्रिप्शन पीकेसीएस # 1 मोड में ठीक काम करता है। – CitadelCore

0

मैं स्मार्टकार्डस के साथ इस आज के साथ बहस कर रहा है (या अधिक सही, स्मार्ट कार्ड PIV एप्लेट के साथ एक Yubikey नव सक्षम);

var encryptor = (RSACryptoServiceProvider)c.PublicKey.Key; 
var decryptor = (RSACryptoServiceProvider)c.PrivateKey; 

var encrypt = encryptor.Encrypt(bytes, RSAEncryptionPadding.Pkcs1); 
var decrypt = decryptor.Decrypt(encrypt, RSAEncryptionPadding.Pkcs1); 

मैंने पाया यह मायने रखता है कि क्या गद्दी algo मैं का उपयोग करें: इस कोड का उपयोग। अगर मैं पीकेसीएस 1 पैडिंग का उपयोग करता हूं, तो सब कुछ काम करता है। अगर मैं OaepSHA1 का उपयोग करता हूं, तो मुझे Error while decoding [...] त्रुटि मिलती है। अगर मैं कुछ और उपयोग करता हूं (उदा।, OaepSHA256) मुझे Not supported त्रुटि मिलती है।

मैं केवल यह निष्कर्ष निकाल सकता हूं कि मेरा स्मार्टकार्ड ओएईपी SHA1 का उचित समर्थन नहीं करता है, लेकिन पीकेसीएस # 1 के साथ पैडिंग सब कुछ अच्छा है।

भले ही यह आपको पहले से पता चले कि यह जवाब देता है, यह स्मार्टकार्ड का उपयोग करके किसी और के लिए आने वाले किसी अन्य डेटापॉइंट के रूप में उपयोगी हो सकता है।

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