Avatar billede Jim Rasmussen Novice
17. juli 2011 - 00:46 Der er 16 kommentarer og
1 løsning

Encrypt/Decrypt

Hej. (:

Jeg har en xml fil som indeholder nogle meget følsomme data. Disse data skal kun være mulige at læse ved brug af det program (wpf project) som xml filen tilhøre.

Har læst på nettet angående kryptering og dekryptering, men har kun fundet nogle (Syns jeg) MEGET komplicerede løsninger. Er det bare en hel ny verden jeg bevæger mig ind i? Har aldrig brugt eller arbejdet med kryptering før

har hørt at Rijndael er en god algoritme. Men er den svær at bruge?
Avatar billede arne_v Ekspert
17. juli 2011 - 00:52 #1
AES (Rijndael) er nem at bruge i .NET.

Det burde ikke vaer svaert at kryptere data og enten base64 encode eller hexificere og saa gemme i XML.

Hvis det skal laeses af andre programmer var det en fordel at bruge XMLSEC standarden, men det lyder som om det ikke er et krav.
Avatar billede arne_v Ekspert
17. juli 2011 - 00:53 #2
Kode snippet:

using System;
using System.Text;
using System.Security.Cryptography;

public class MainClass
{
    private static Encoding utf = new UTF8Encoding();
    private static Rijndael aes = new RijndaelManaged();
    private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
    public static string Encrypt(string plain, string key)
    {
        ICryptoTransform encrypt = aes.CreateEncryptor(utf.GetBytes(key), iv);
        return Convert.ToBase64String(encrypt.TransformFinalBlock(utf.GetBytes(plain), 0, utf.GetByteCount(plain)));
    }
    public static string Decrypt(string cipher, string key)
    {
        ICryptoTransform decrypt = aes.CreateDecryptor(utf.GetBytes(key), iv);
        byte[] b = Convert.FromBase64String(cipher);
        return utf.GetString(decrypt.TransformFinalBlock(b, 0, b.Length));
    }
    public static void Main(string[] args)
    {
        Console.WriteLine(Encrypt("Dette er en test !", "hemmeligabcdefgh12345678"));
        Console.WriteLine(Decrypt(Encrypt("Dette er en test !", "hemmeligabcdefgh12345678"), "hemmeligabcdefgh12345678"));
    }
}

Encrypt og Decrypt metoderne skulle vaere lige til at bruge.

Hvis det skal vaere helt rigtigt skal du bruge forskellige iv, men ...
Avatar billede amews_aj Nybegynder
17. juli 2011 - 02:00 #3
Blot for at gøre det mere tydeligt:
Der menes ikke forskellig IV til hhv. at kryptere og dekryptere, men derimod at IV skal vælges forskellig hver gang du krypterer noget (aldrig genbruge IV's).
Den IV der blev brugt til at kryptere med skal også bruges til at dekryptere med.
Dog er IV som sådan ikke hemmelig, og du kan derfor gemme den sammen med dine data ukrypteret, og således let finde den når du skal dekryptere.

Formålet med IV er at sikre, at hvis man krypterer samme data flere gange, så fås stadig forskellig output ved kryptering. Det giver en øget sikkerhed.
Avatar billede riversen Nybegynder
17. juli 2011 - 09:10 #4
#3: Hvorfor er argumentèt sikkerhed mht. ikke at genbruge iv, hvis du siger, at man uden problemer kan gemme den ukrypteret sammen med data?
Avatar billede riversen Nybegynder
17. juli 2011 - 09:13 #5
og kan man ikke nemt decompilere koden og få fat i nøglen?
Avatar billede bvli Praktikant
17. juli 2011 - 12:08 #6
#4 tænk "salt"
#5 jo

Koden er som key'en kan bindes på den konto programmet køres under. På samme måde som når man krypterer sections i web.config. Jeg tror jeg har et eksempel et sted.
Avatar billede bvli Praktikant
17. juli 2011 - 12:19 #7
using System.Configuration;
using System.Xml;
using System.Xml.Linq;

namespace B.Testing {

    static class StringEncryptionExtensions {

        public static string Encrypt(this string argument) {
            if (string.IsNullOrEmpty(argument) throw new ArgumentException("argument is null or empty.", "argument");
            DpapiProtectedConfigurationProvider cp = new DpapiProtectedConfigurationProvider();
            XmlElement n = new XmlDocument().CreateElement("temp");
            n.InnerText = argument;
            return cp.Encrypt(n).FirstChild.FirstChild.InnerText;
        }

        public static string Decrypt(this string argument) {
            if (string.IsNullOrEmpty(argument) throw new ArgumentException("argument is null or empty.", "argument");
            DpapiProtectedConfigurationProvider cp = new DpapiProtectedConfigurationProvider();
            XElement e = new XElement("EncryptedData", new XElement("CipherData", new XElement("CipherValue", argument)));
            using (XmlReader xr = e.CreateReader()) {
                XmlDocument d = new XmlDocument();
                d.Load(xr);
                return cp.Decrypt(d.FirstChild).InnerText;
            }
        }
    }
}

---
Koden bruger Windows DPapi til at kryptere stringen med. Dvs. krypteringen er bundet op på dine windows credentials (eller de credentials programmet kører under).
Avatar billede amews_aj Nybegynder
17. juli 2011 - 12:42 #8
#4, som bvli siger, tænk 'salt'.
Altså, IV har intet med key at gøre, og du kan ikke bruge IV til noget uden også at have koden. Altså det er ikke sådan du kan delvis dekryptere alene med IV.
Hvis man aldrig genbruger IV's, så vil man ikke kunne se på krypteret data (selvom IV ikke er krypteret) ligheder imellem oprindelig data.
Avatar billede amews_aj Nybegynder
17. juli 2011 - 12:44 #9
"...uden også at have koden" -> "...uden også at have key'en"

#5, I princippet jo, og nøglen bør derfor ikke hardcodes ned i programmet.
Avatar billede arne_v Ekspert
17. juli 2011 - 20:16 #10
Med hensyn til iv saa er der forskellige problemer med genbrug af iv. Nogen af dem er lidt tekniske, men lad os tage et eksempel som er saa simpelt at alle kan foelge med.

Riversen du bliver ansat af Warren Buffet til at handle aktier i Maersk.

Hver aften sender Buffet dig en email med et ord "Buy" eller "Sell" og saa handler du dagen efter.

Da det aabenlyst er interessant at vide om Buffer koeber eller saelger, saa krypteres den email. Buffet og dig har key'en.

Den skumle sidegade vekseler arne_v opsnapper emailene.

Uden iv:

17/7: Buffet sender msg=HJTW
18/7: du koeber, Buffet sender msg=LQZP
19/7: du saelger, Buffet sender msg=HJTW
20/7: du koeber,  Buffet sender msg=LQZP
21/7: jeg saelger fordi jeg ved at du vil saelge

Med iv:

17/7: Buffet sender iv=317,msg=JAGW
18/7: du koeber, Buffet sender iv=922,msg=QBFS
19/7: du saelger, Buffet sender iv=731,msg=AHJA
20/7: du koeber,  Buffet sender iv=693,msg=AJKT
21/7: jeg skifter erhverv
Avatar billede arne_v Ekspert
17. juli 2011 - 20:21 #11
Avatar billede clausc Nybegynder
18. juli 2011 - 09:51 #12
OP skriver 'meget følsomme data'.

Er der eksterne krav? I så fald bør du være helt sikker på, om de krav indebærer at dine nøgler aldrig må optræde i klar (heller ikke i RAM i meget kort tid). Hvis det er tilfældet, så skal du (som ny i den verden) overveje ekstern hjælp - og forberede dig på at løsningen er meget dyr.

Pointen er, at løsninger med 'meget følsomme data' ofte har kunder, der forventer sikkerhed via hardware moduler, og det vil være yderst uheldigt at opdage det sent i forløbet.
Avatar billede Jim Rasmussen Novice
31. juli 2011 - 16:30 #13
Hej. Ved ikke om jeg satser for højt??

Programmet køre i windows jo, og lader brugeren gemme sine personlig /følsomme data via programmet i en xml fil. Programmet skal gøre det nemt for brugeren at tilgå login's og andre personlige data med blot et login.

Windows har vel en form for beskyttelse for ubudne gæster udefra ikke?? Så er en hashing ikke nok i dette tilfælde?

Det skal bare beskytte andre brugere af computeren fra at læse det der står i xml filen ved at åbne den. (:
Avatar billede arne_v Ekspert
31. juli 2011 - 18:37 #14
Hashing er envejs.

Det er muligt at Caesar er godt nok til dit formaal.

Men hvad koster det ekstra at bruge en moderne algoritme??
Avatar billede bvli Praktikant
01. august 2011 - 16:57 #15
Men altså - det er vel lige præcis det den kodestump jeg postede gør for dig.

string stuff = dinXml.ToString();
string encryptedStuff = stuff.Encrypt();

using (Stream stream = File.Open("pathTilDinSettingsFile_EllerEndnuBedre_IsolatedStorage"))
using (TextWriter writer = new StreamWriter(stream)) {
  writer.Write(encryptedStuff);
}

Og når du skal loade igen:

using (Stream stream = File.Open("pathTilDinSettingsFile_EllerEndnuBedre_IsolatedStorage"))
using (TextReader reader = new StreamReader(stream)) {
  string encryptedStuff = reader.ReadLine();
  string stuff = encryptedStuff.Decrypt();
  XDocument dinXml = XDocument.Parse(stuff);
}

Det er vel egentlig ret ligetil eller hur?
Avatar billede Jim Rasmussen Novice
01. august 2011 - 20:39 #16
arne_v..

Kan du ikke sende et svar (:
Avatar billede arne_v Ekspert
01. august 2011 - 20:47 #17
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester