Verschlüsselung im NAV

27. Oktober 2014 13:14

Hallo Gemeinde,

ich bräuchte wieder mal Rat bei einem eher exotischen Problem. Aktuell benötige ich eine Möglichkeit einen String im Navision zu verschlüsseln (am besten synchron mittels einer Passphrase), welcher dann wieder entschlüsselt werden kann. Ich habe mir bereits einen Artikel bei mibuso http://mibuso.com/blogs/kirtangor/2010/03/23/implementing-encryption-in-microsoft-dynamics-nav/ angeschaut, welcher den 3DES Algorithmus verwendet, der vollkommen ausreichend wäre, allerdings werd ich nicht wirklich schlau daraus bzw. weiß nicht wie ich diese Methode umsetzen soll oder wo die Passphrase angeben wird. Vielleicht hat jemand schon Erfahrungen mit dem Thema gemacht und weiß einen Lösung mit den Navision Boardmitteln. Vielen Dank schon mal im Voraus.
Zuletzt geändert von jkahnt am 4. November 2014 10:14, insgesamt 1-mal geändert.

Re: Verschlüsselung im NAV

28. Oktober 2014 15:49

hmm,
der Artikel beschreibt die Vorgehensweise doch ganz gut.
Vielleicht fangen wir einfach mal mit der Anfoderung an...
was genau willst du erreichen (String verschlüsseln reicht hier wohl an der Stelle nicht aus, um deine Herausforderung zu lösen)

Re: Verschlüsselung im NAV

28. Oktober 2014 21:20

hi,

beispielcode:

die variablen:
----------------------------------------------------------------------------
Name DataType Subtype Length
TripleDESEnc DotNet System.Security.Cryptography.TripleDES.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
sData Text 1024
FileName Text 1024
fStream DotNet System.IO.FileStream.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
fMode DotNet System.IO.FileMode.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
cStream DotNet System.Security.Cryptography.CryptoStream.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
cMode DotNet System.Security.Cryptography.CryptoStreamMode.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
cEnc DotNet System.Security.Cryptography.ICryptoTransform.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
sWriter DotNet System.IO.StreamWriter.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
file File
cKey DotNet System.Byte.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
initVector DotNet System.Byte.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
cDec DotNet System.Security.Cryptography.ICryptoTransform.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
sReader DotNet System.IO.StreamReader.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
TripleDESDec DotNet System.Security.Cryptography.TripleDES.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
----------------------------------------------------------------------------

der code:
----------------------------------------------------------------------------
Code:
sData := 'Here is some data to encrypt.';
FileName := 'c:\temp\CText.txt';

// encrypt
fMode := fMode.OpenOrCreate;
fStream := fStream.FileStream(FileName,fMode);

TripleDESEnc := TripleDESEnc.Create('TripleDES');
cEnc := TripleDESEnc.CreateEncryptor;

cMode := cMode.Write;
cStream := cStream.CryptoStream(fStream,cEnc,cMode);
sWriter := sWriter.StreamWriter(cStream);
sWriter.WriteLine(sData);

sWriter.Close;
cStream.Close;
fStream.Close;

file.OPEN(FileName);
file.READ(sData);
file.CLOSE;

MESSAGE('Encrypted: ' + sData);

// decrypt
fMode := fMode.OpenOrCreate;
fStream := fStream.FileStream(FileName, fMode);

TripleDESDec := TripleDESDec.Create;
cDec := TripleDESDec.CreateDecryptor(TripleDESEnc.Key,TripleDESEnc.IV);

cMode := cMode.Read;
cStream := cStream.CryptoStream(fStream,cDec,cMode);
sReader := sReader.StreamReader(cStream);
sData := sReader.ReadLine;

sReader.Close;
cStream.Close;
fStream.Close;

MESSAGE('Decrypted: ' + sData);


regards
Zuletzt geändert von Kowa am 4. November 2014 09:57, insgesamt 1-mal geändert.
Grund: Code-Tags ergänzt

Re: Verschlüsselung im NAV

3. November 2014 13:37

Hallo archer,

vielen Dank für das sehr umfangreiche Beispiel. Mir ist jetzt leider nur noch nicht klar wie ich dem encoder den Key übergeben kann.

Re: Verschlüsselung im NAV

3. November 2014 14:08

Du kannst CreateEncryptor(Byte[], Byte[]) und CreateDecryptor(Byte[], Byte[]) mit deinem Key und Initialisierungsvektor überladen. (Link)

In dem obigen Fall wird beides in CreateEncryptor() vermutlich per Zufall bestimmt bzw. das was TripleDESEnc.Key und TripleDESEnc.IV zugewiesen ist.

Wenn die aktuelle Key-Eigenschaft null ist, wird die GenerateKey-Methode aufgerufen, um einen neuen Zufallswert für Key zu erstellen. Wenn die aktuelle IV-Eigenschaft null ist, wird die GenerateIV-Methode aufgerufen, um einen neuen Zufallswert für IV zu erstellen.


mfg,
winfy

Re: Verschlüsselung im NAV

3. November 2014 16:25

Hallo Winfy,

vielen Dank für die Antwort, das bringt mich gleich zur nächsten Frage:

Wie erzeuge ich am einfachsten ein Byte-Array welches ich dem Konstruktor übergeben kann.

Meine bisherigen Versuche waren ein char-Array zu füllen und danach ein .net - Byte Array wobei ich allerdings einen Fehler bei der Zuweisung bekomme:

Bsp.:

Array.SetValue('a', 0);

Fehler:

Fehler beim Aufrufen von 'System.Byte[].SetValue': Die Erweiterung von Quelltyp zu Zieltyp ist nicht möglich. Entweder ist der Quelltyp kein primitiver Typ, oder die Umwandlung kann nicht durchgeführt werde.

ich habe auch schon versucht es vorher in eine char-Variable zu schreiben und dann diese mit SetValue zuzuweisen, mit dem gleichen Ergebnis. Meines Wissens nach wird char automatisch in byte gewandelt oder versteh ich die Fehlermeldung falsch.

Vielen dank im voraus.

[EDIT]:

Array wird wie folgt erzeugt:

Array DotNet System.Array.'mscorlib, Version=4.0.0.0, Culture=neutral,...
ArrayType DotNet System.Type.'mscorlib, Version=4.0.0.0, Culture=neutral,...

In C/AL:

ArrayType := ArrayType.GetType('System.Byte',FALSE);
Array := Array.CreateInstance(ArrayType, 16);

Re: Verschlüsselung im NAV

3. November 2014 16:33

Ich habe meinen Fehler selber gefunden. Den Datentyp Byte gibt es ja jetzt in 2013 und ich hatte in eine 2009er Anleitung geschaut :oops:

Re: Verschlüsselung im NAV

4. November 2014 09:47

Hallo Gemeinde,

ich muss mich nochmal melden (kurz vor dem Ziel). Ich habe das Beispiel von Archer jetzt adaptiert und alles funktioniert auch so wie es soll. Auch der verschlüsselte String passt .... fast. Ich habe das Problem das der Stream in den geschrieben wird einfach zu lang ist und somit der Ergebnisstring (den ich noch Base64 codiere) zu lang wird. Im Prinzip wird er mit AAAAA... aufgefüllt was wahrscheinlich bei leeren Zeichen herauskommt. Vermutlich ist es nur eine kleine Anpassung aber ich bin bis jetzt noch nicht drauf gekommen. Hier auch kurz mein Code und ein Screenshot vom Base64 codierten String:
Code:
Variablen
      SourceString@1119455000 : Text[1024];
      TargetString@1119455001 : Text[1024];
      AESEnc@1119455015 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Security.Cryptography.Aes";
      cEnc@1119455016 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Security.Cryptography.ICryptoTransform";
      cMode@1119455025 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Security.Cryptography.CryptoStreamMode";
      cPadding@1119455008 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Security.Cryptography.PaddingMode";
      cStream@1119455026 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Security.Cryptography.CryptoStream";
      sWriter@1119455027 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.StreamWriter";
      dStream@1119455002 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.MemoryStream";
      dBytes@1119455003 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Array";
      dConvert@1119455004 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Convert";
      CharIndex@1119455018 : Integer;
      KeyString@1119455019 : Text[32];
      KeyCharArr@1119455020 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Array";
      CipherMode@1119455021 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Security.Cryptography.CipherMode";
      ArrayType@1119455022 : DotNet "'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Type";
      TmpByte@1119455023 : Byte;

Code:

                  SourceString := 'ABC';
                  KeyString := 'abcdefghijklmnoqprstuvwxyz012345';
                  ArrayType := ArrayType.GetType('System.Byte',FALSE);
                  KeyCharArr := KeyCharArr.CreateInstance(ArrayType,STRLEN(KeyString));

                  FOR CharIndex := 1 TO STRLEN(KeyString) DO BEGIN
                    TmpByte := KeyString[CharIndex];
                    KeyCharArr.SetValue(TmpByte,CharIndex - 1);
                  END;

                  AESEnc := AESEnc.Create('AesManaged');
                  AESEnc.KeySize(256);
                  AESEnc.Mode(CipherMode.ECB);
                  AESEnc.Key(KeyCharArr);
                  AESEnc.Padding(cPadding.Zeros);

                  cEnc := AESEnc.CreateEncryptor;

                  cMode := cMode.Write;

                  dStream := dStream.MemoryStream();

                  cStream := cStream.CryptoStream(dStream, cEnc, cMode);

                  sWriter := sWriter.StreamWriter(cStream);
                  sWriter.AutoFlush(TRUE);
                  sWriter.Write(SourceString);

                  cStream.FlushFinalBlock;

                  sWriter.Close;

                  dBytes := dStream.GetBuffer();

                  TargetString := dConvert.ToBase64String(dBytes);

                  MESSAGE('Encrypted = %1', TargetString);


EDIT: die A Zeichen stehen für den Wert 0 und das = sind Füllzeichen bei Base64, sprich das Byte Array ist leer ab dieser Stelle
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Zuletzt geändert von jkahnt am 4. November 2014 10:53, insgesamt 2-mal geändert.

Re: Verschlüsselung im NAV

4. November 2014 09:56

Bitte die Code-Tags bei der Formatierung der Beiträge nutzen.

Re: Verschlüsselung im NAV

4. November 2014 20:50

hallo jkahnt,

probier mal die Text Variablen ohne Länge zu benutzen.
alternativ: den resulting string einfach kürzen. string endet wahrsch. mit einer serie von 0 bytes od. derleichen.

regards

Re: Verschlüsselung im NAV

10. Juli 2015 12:25

Hallo zusammen,

geht sowas auch im Classic Client?