2016-11-23 36 views
5

Mam app netto rdzenia stosując core1.1 Podczas migracji moduł CRIPT/decript ze starej .NET4.6 do rdzenia netto to tylko przyzwyczajenie pracaTripleDES. Określony tryb wyściółka nie jest ważny dla tego algorytmu

First TripleDES nie (używał) obsługuje 128-bitowe klucze i jest naprawiony kluczami 192-bitowymi, próba zmiany powoduje błąd.

drugie, starając się decript ten ciąg:

/Tk0ydguv3HauCVUWDK3Tr6U8c9BBaaRwtSt5q4/uHg=

TripleDES uruchamia błąd z PKCS7 Padding Saing "Tryb wyściółka jest nieprawidłowy dla tego algorytmu." Co jest dziwne, ponieważ ti jest wypełnieniem domyślnym.

Moja project.json:

{ 
    "dependencies": { 
    "Microsoft.NETCore.App": { 
     "version": "1.1.0", 
     "type": "platform" 
    }, 
    "Microsoft.AspNetCore.Diagnostics": "1.1.0", 
    "Microsoft.AspNetCore.Mvc": "1.0.1", 
    "Microsoft.AspNetCore.Razor.Tools": { 
     "version": "1.0.0-preview2-final", 
     "type": "build" 
    }, 
    "Microsoft.AspNetCore.Routing": "1.0.1", 
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", 
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.1", 
    "Microsoft.AspNetCore.StaticFiles": "1.0.0", 
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", 
    "Microsoft.Extensions.Configuration.Json": "1.0.0", 
    "Microsoft.Extensions.Logging": "1.0.0", 
    "Microsoft.Extensions.Logging.Console": "1.0.0", 
    "Microsoft.Extensions.Logging.Debug": "1.0.0", 
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", 
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0", 
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", 
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", 
    "Microsoft.EntityFrameworkCore.Design": "1.0.0-preview2-final", 
    "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1", 
    "Microsoft.AspNetCore.Mvc.WebApiCompatShim": "1.0.1", 
    "Microsoft.AspNetCore.Session": "1.0.0", 
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" 
    }, 

    "tools": { 
     "BundlerMinifier.Core": "2.0.238", 
     "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-preview3-final", 
     "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", 
     "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" 
    }, 

    "frameworks": { 
    "netcoreapp1.1": { 
     "imports": [ 
      "portable-net461+win8" 
     ] 
    } 
    }, 

    "buildOptions": { 
    "emitEntryPoint": true, 
    "preserveCompilationContext": true 
    }, 

    "runtimeOptions": { 
    "configProperties": { 
     "System.GC.Server": true 
    } 
    }, 

    "publishOptions": { 
    "include": [ 
     "wwwroot", 
     "**/*.cshtml", 
     "appsettings.json", 
     "web.config" 
    ] 
    }, 

    "scripts": { 
    "prepublish": [ "bower install", "dotnet bundle" ], 
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] 
    } 
} 

Mój kod:

using System; 
using System.Security.Cryptography; 
using System.Text; 
namespace WebApp.Class 
{ 
    public class Md5 
    { 
     private static readonly byte[] IV = { 240, 3, 45, 29, 0, 76, 173, 59 }; 

     const int NumCryptokey = 6; 
     const int NumExtraClave = 8; 
     const int NumsKey = 7; 


     public static string Generate(int KeyChars) 
     { 
      int i_key = 0; 
      float Random1 = 0; 
      Int16 arrIndex = default(Int16); 
      StringBuilder sb = new StringBuilder(); 
      char RandomLetter; 

      string KeyLetters = "abcdefghijklmnopqrstuvwxyz"; 
      string KeyNumbers = ""; 

      char[] LettersArray = null; 
      char[] NumbersArray = null; 

      LettersArray = KeyLetters.ToCharArray(); 
      NumbersArray = KeyNumbers.ToCharArray(); 

      for (i_key = 1; i_key <= KeyChars; i_key++) 
      { 
       Random random = new Random(); 
       Random1 = random.Next(); 

       arrIndex = -1; 
       if ((Convert.ToInt32(Random1 * 111)) % 2 == 0) 
       { 
        while (arrIndex < 0) 
        { 
         arrIndex = Convert.ToInt16(LettersArray.GetUpperBound(0) * Random1); 
        } 
        RandomLetter = LettersArray[arrIndex]; 
        if ((Convert.ToInt32(arrIndex * Random1 * 99)) % 2 != 0) 
        { 
         RandomLetter = LettersArray[arrIndex]; 
         RandomLetter = char.ToUpper(RandomLetter); 
        } 
        sb.Append(RandomLetter); 
       } 
       else 
       { 
        while (arrIndex < 0) 
        { 
         arrIndex = Convert.ToInt16(NumbersArray.GetUpperBound(0) * Random1); 
        } 
        sb.Append(NumbersArray[arrIndex]); 
       } 
      } 
      return sb.ToString(); 
     } 

     public static string Encriptar(string serializedQueryString) 
     { 
      string functionReturnValue = null; 
      string sRetorno = null; 
      try 
      { 
       string cryptokey = ""; 
       string ExtraClave = ""; 
       string sKey = ""; 

       cryptokey = Generate(NumCryptokey); 
       ExtraClave = Generate(NumExtraClave); 
       sKey = Generate(NumsKey); 

       byte[] buffer = Encoding.ASCII.GetBytes(serializedQueryString + ExtraClave); 
       var des = TripleDES.Create(); 
       var MD5 = System.Security.Cryptography.MD5.Create(); 
       des.Key = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(sKey + cryptokey)); 
       des.IV = IV; 

       sRetorno = cryptokey + ExtraClave + sKey + Convert.ToBase64String(des.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length)); 

       functionReturnValue = sRetorno; 
      } 
      catch (Exception ex) 
      { 
       functionReturnValue = ""; 
      } 
      return functionReturnValue; 

     } 

     public static string Desencriptar(string encryptedQueryString) 
     { 
      string functionReturnValue = null; 
      byte[] buffer = null; 
      var DES = System.Security.Cryptography.TripleDES.Create(); 
      var Md5 = MD5.Create(); 
      string sRetorno = null; 

      string cryptokey = ""; 
      string ExtraClave = ""; 
      string sKey = ""; 

      cryptokey = encryptedQueryString.Substring(0,NumCryptokey); 
      ExtraClave = encryptedQueryString.Substring(NumCryptokey, NumExtraClave); 
      sKey = encryptedQueryString.Substring(NumCryptokey + NumExtraClave, NumsKey); 

      encryptedQueryString = encryptedQueryString.Substring(NumCryptokey + NumExtraClave + NumsKey, encryptedQueryString.Length-(NumCryptokey + NumExtraClave + NumsKey)); 

      try 
      { 
       buffer = Convert.FromBase64String(encryptedQueryString); 
      byte[] by = new byte[24]; 
       by = Md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(sKey + cryptokey)); 
      Array.Resize(ref by, 24); 
       DES.Key = by; 
       DES.IV = IV; 

       sRetorno = Encoding.ASCII.GetString(DES.CreateDecryptor().TransformFinalBlock(buffer, 0, buffer.Length)).Replace(ExtraClave, ""); 
       functionReturnValue = sRetorno; 
      } 
      catch (Exception ex) 
      { 
       functionReturnValue = ""; 
      } 
      return functionReturnValue; 

     } 
    } 
} 
+0

Zamiast tego użyj wypełnienia PKCS5. Technicznie PKCS # 7 jest zdefiniowany dla szyfrów 128-bitowych, podczas gdy PKCS # 5 dla 64-bitowych szyfrów, takich jak DES. Twoja implementacja może być wybredna. – rossum

+1

@rossum: W rzeczywistości PKCS # 7 nie ma żadnych założeń co do rozmiaru bloku, w przeciwieństwie do PKCS # 5. –

+0

OK, dzięki za poprawkę. – rossum

Odpowiedz

0

Znaleziono!

public static string Encriptar(string serializedQueryString) 
    { 
     string functionReturnValue = null; 
     string sRetorno = null; 
     try 
     { 
      string cryptokey = ""; 
      string ExtraClave = ""; 
      string sKey = ""; 

      cryptokey = Generate(NumCryptokey); 
      ExtraClave = Generate(NumExtraClave); 
      sKey = Generate(NumsKey); 

      byte[] buffer = Encoding.ASCII.GetBytes(serializedQueryString + ExtraClave); 
      var des = TripleDES.Create(); 
      var Md5 = MD5.Create(); 

      byte[] by = new byte[24]; 
      by = Md5.ComputeHash(Encoding.ASCII.GetBytes(sKey + cryptokey)); 
      Array.Resize(ref by, 24); 
      Array.Copy(by, 0, by, 16, 8); 
      des.Key = by; 
      des.IV = IV; 
      //es.Padding = PaddingMode.None; 
      sRetorno = cryptokey + ExtraClave + sKey + Convert.ToBase64String(des.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length)); 

      functionReturnValue = sRetorno; 

     } 
     catch (Exception ex) 
     { 
      functionReturnValue = ""; 
     } 
     return functionReturnValue; 
    } 
-2

I w obliczu tego samego problemu w ASP.NET Core. Jednak nie podawałem żadnej IV.

Właśnie dodałem tę linię podczas szyfrowania oraz odszyfrowywania po określeniu klucza.

DES3.IV = new byte[DES3.BlockSize/8]; 

Bez tej linii wystąpił błąd opisany powyżej.

Zgodnie docs na https://msdn.microsoft.com/en-us/library/system.security.cryptography.symmetricalgorithm.iv(v=vs.110).aspx

The IV property is automatically set to a new random value whenever you create a new instance of one of the SymmetricAlgorithm classes or when you manually call the GenerateIV method.

Jednak ja nadal nie rozumiem, dlaczego to działa, gdyż nawet próbowałem podając wartości statycznych do IV (jak twoje w pytaniu) & nie udało się nawet wtedy.

+0

Użyj losowego IV, po prostu dodaj kodowanie dane z IV do użytku w deszyfrowaniu, nie musi nie tajne. W przeciwnym razie identyczne wiadomości lub wiadomości o tym samym początku będą miały te same zaszyfrowane dane, a informacje zostaną ujawnione. Również wyjaśnienie, dlaczego to zadziałało, czyni odpowiedź bardziej użyteczną. – zaph

+0

@Zaph Próbowałem używać statycznego IV, ale to się nie udawało. Nadal nie wiem, dlaczego to zadziałało !! –

+0

Jeśli automatycznie generowany losowy IV jest używany, musi zostać pobrany i użyty do późniejszego odszyfrowania.Jednym ze sposobów radzenia sobie z IV jest przedrost zaszyfrowanych danych z IV do wykorzystania w deszyfrowaniu, nie musi nie być tajny. – zaph