2016-07-12 35 views
10

Come utilizziamo la crittografia Rijndael in una libreria di classi .Net Core? (Non una libreria di classi .Net Framework) Abbiamo bisogno di creare una libreria Core .Net condivisa da utilizzare in più progetti e abbiamo bisogno di implementare metodi Encrypt e Decrypt che utilizzano la stessa crittografia Rijndael attraverso i progetti.Come utilizzare la crittografia Rijndael con una libreria di classi .Net Core? (Not .Net Framework)

Attualmente stiamo utilizzando:

  • VS Enterprise 2015

Sembra C#

  • Libreria di classi .NET Nucleo
  • .NETStandard, Version = riferimento v1.6 che l'implementazione di Rijndael e AES non è presente nella versione .Net Core 1.0 ... sembra che includa solo le classi di base. Come si ottiene un'implementazione .Net Core di Rijndael o crittografia AES aggiunta come riferimento a un nuovo progetto .Net Core Class Library?

    Qui è il metodo Encrypt che funziona in Net Framework 4.5.2:

    public static string Encrypt(string valueToEncrypt, string symmetricKey, string initializationVector) 
        { 
         string returnValue = valueToEncrypt; 
    
         var aes = new System.Security.Cryptography.RijndaelManaged(); 
         try 
         { 
          aes.Key = ASCIIEncoding.ASCII.GetBytes(symmetricKey); 
          aes.IV = ASCIIEncoding.ASCII.GetBytes(initializationVector); 
          aes.Mode = CipherMode.CBC; 
          aes.Padding = PaddingMode.ISO10126; 
    
          var desEncrypter = aes.CreateEncryptor(); 
          var buffer = ASCIIEncoding.ASCII.GetBytes(valueToEncrypt); 
    
          returnValue = Convert.ToBase64String(desEncrypter.TransformFinalBlock(buffer, 0, buffer.Length)); 
         } 
         catch (Exception) 
         { 
          returnValue = string.Empty; 
         } 
    
         return returnValue; 
        } 
    
  • +1

    Qual è il problema in .NET Nucleo? Manca una biblioteca? –

    +2

    Sembra che sia sulla roadmap per la versione 1.1: https://github.com/dotnet/corefx/issues/9984 –

    +0

    Nate corretto, il problema principale sembra essere che l'implementazione di Rijndael manchi dal riferimento di Cryptography nell'attuale versione di .Net Core ... solo implementazioni astratte di classe Base. – Ensunder

    risposta

    19

    La differenza (NET) tra Rijndael e AES Rijndael è che permette la dimensione del blocco di cambiare, ma fa AES non. Poiché la dimensione del blocco predefinito di RijndaelManaged è la stessa della dimensione del blocco AES (128 bit/16 byte), in realtà, si utilizza AES.

    Invece di creare un'istanziazione del tipo di implementazione per nome, è sufficiente utilizzare la fabbrica (Aes.Create()). Funziona sia in .NET Core che in .NET Framework.

    Altre cose da segnalare:

    • casi Tutti SymmetricAlgorithm sono IDisposable, li si dovrebbe usare in un comunicato using.
    • Tutte le istanze di ICryptoTransform (ad esempio il nome errato desEncryptor) sono IDisposable, è necessario utilizzarle in un'istruzione using.
    • Il riempimento ISO10126 non è disponibile in .NET Core 1.0. Se è necessario essere compatibili con gli stream esistenti, è possibile applicare il padding autonomamente e specificare PaddingMode.None. Altrimenti, PKCS7 è più standard.
    • La chiave AES non è molto casuale, poiché proviene da una stringa ASCII (molti valori non saranno validi).
      • Base64 almeno ha gamma pieno valore
      • PBKDF2 (basata su password chiave Derivazione funzione 2) tramite i Rfc2898DeriveBytes classe consente di condiviso-string-segreto, il rumore prevedibile fuori.
      • KeyAgreement è in generale migliore, ma né ECDH né il classico DH sono disponibili in .NET Core 1.0.
    • In genere il codificatore deve consentire di calcolare un IV casuale (chiamare aes.GenerateIV() se si utilizza lo stesso oggetto per più operazioni) e presentarlo con il testo cifrato. Quindi cripta prende una chiave e un testo in chiaro e produce un testo cifrato e IV. Decifratura prende (chiave, IV, testo cifrato) e produce testo in chiaro.
    +0

    bartonjs: scusa se questa è una domanda stupida, ma ho provato a cercare come farlo ... come avrei applicato manualmente il padding ISO10126? Dobbiamo essere compatibili con i flussi esistenti. – Ensunder

    +0

    Estendi la matrice da allineare in blocco (aggiungendo un altro blocco se lo è già) e compila per https://en.wikipedia.org/wiki/Padding_(cryptography)#ISO_10126. Se si utilizzano flussi, è possibile scaricarli in un array o creare un ICryptoTramsform personalizzato per avvolgere quello corrente e applicare/rimuovere il riempimento in TransformFinalBlock. (La trasformazione personalizzata funzionerebbe anche per i byte diretti, ovviamente). – bartonjs

    +0

    Quando si utilizza CFB con NoPadding. CreateEncryptor creato da Aes non può avere InputBlockSize == 1. RijndaelManaged non ha questo problema. – Diryboy

    0

    Se si desidera solo per cifrare/decifrare roba, evitare di utilizzare Rijndael direttamente come nucleo asp.net ha alcuni involucri molto più belli che sono molto più facili da usare e più probabilità di essere adeguatamente protetto per impostazione predefinita. È noto come DataProtection.

    using Microsoft.AspNetCore.DataProtection; 
    
    // During startup add DP 
    serviceCollection.AddDataProtection(); 
    
    ... 
    
    // the 'provider' parameter is provided by DI 
    public MyClass(IDataProtectionProvider provider) 
    { 
        _protector = provider.CreateProtector("Contoso.MyClass.v1"); 
    } 
    
    ... 
    
    // protect the payload 
    string protectedPayload = _protector.Protect(input); 
    Console.WriteLine($"Protect returned: {protectedPayload}"); 
    
    ... 
    
    // unprotect the payload 
    string unprotectedPayload = _protector.Unprotect(protectedPayload); 
    Console.WriteLine($"Unprotect returned: {unprotectedPayload}"); 
    

    Vedere la data protection docs per ulteriori informazioni